Как сохранить двухстороннее связанное значение при изменении как текста данных, так и источника элементов WPF ComboBox - PullRequest
0 голосов
/ 07 февраля 2020

Фон

Приложение имеет представление списка, связанное со списком «Заданий», свойства которых редактируются некоторыми выпадающими списками (с двухсторонним связыванием). Контекст данных комбинированных списков изменяется на текущий выбранный job с помощью события SelectionChanged представления списка.

Значение комбинированного списка связано со свойством Job. itemssource задания изменяется на совершенно другой список после DataContextChanged.

Компоновка виджетов

Выпуск

Связанное свойство со списком заданий задано равным нулю при изменении DataContext.

При просмотре списка заданий все свойства, связанные с любым комбинированным списком, устанавливаются в нуль.

Предполагаемая проблема

Я могу ошибаться в этом предположении ...

При переключении datacontext либо старый выбранный Job, либо новый выбранный Job устанавливается равным нулю, как это делает источник элементов. n для хранения значений в одном из новых или старых выбранных Job.

попыток отладки (Правка)

Я заметил значение свойство Job было установлено равным нулю до изменения SelectedItem списка заданий.

Вопрос

Как можно значение связанного свойство Job сохраняется при переключении текстового контекста ComboBox на источник данных, который не содержит SelectedValue? * 10 53 *

Соответствующий код (Сокращенный - Привязка к другим виджетам работает как положено)

<ComboBox x:Name="ContactField" Grid.Column="1"  Grid.Row="3" Margin="2,1" Grid.ColumnSpan="3" DisplayMemberPath="Value" SelectedValuePath="Id" SelectedValue="{Binding Contact,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectionChanged="ContactField_SelectionChanged"/>

Код сзади - Изменение элементов источника

private void UpdateCustomerDependancies() 
{

    imprintDataSetTableAdapters.CustomerContactsTableTableAdapter rpcdtta = new imprintDataSetTableAdapters.CustomerContactsTableTableAdapter();
    IList<ComboData> customers = new List<ComboData>();

    if (LeftFieldPanel.DataContext != null) //Where LeftFieldPanel contains all comboboxes
    {
        Job currentJob = (Job)LeftFieldPanel.DataContext;

        foreach (DataRow item in rpcdtta.GetDataBy(currentJob.CustomerCode).Rows)
        {
            customers.Add(new ComboData() { Id = item.ItemArray[0].ToString(), Value = item.ItemArray[1].ToString() });
        }
        ContactField.ItemsSource = customers;

    }
}

Код позади - изменение контекста данных

private void jobTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        if (jobTree.SelectedItem.GetType() == typeof(Job))
        {
            DelGrid.Visibility = Visibility.Hidden;


            Job j = (Job)jobTree.SelectedItem;


            MessageBox.Show(j.Contact);

            LeftFieldPanel.DataContext = j; //Switch datacontext
            RightFieldPanel.DataContext = j; //switchdata context

        }


    }

1 Ответ

1 голос
/ 10 февраля 2020

Согласно этому ответу и моим собственным исследованиям невозможно просто связать и надеяться на это лучшее. Таким образом, моя работа заключается в следующем. Я обобщил код, чтобы сделать его применимым к другим обстоятельствам.

1) После изменения текста данных добавьте новые элементы в список, не удаляя старые:

private void ListView1_SelectedItemChanged(...) {
    List<ComboData> comboitems = ((IList<ComboData>)ComboBox1.ItemsSource).ToList(); 
    //Add new items to comboitems here
    ComboBox1.ItemsSource = comboitems; //Rebind
}

2) Открыв выпадающий список, получите источник предметов и удалите только старые предметы

private void ComboBox1_DropDownOpened(...) {
    List<ComboData> comboitems = ((IList<ComboData>)ComboBox1.ItemsSource).ToList(); 
    //Remove old items from comboitems here
    ComboBox1.ItemsSource = comboitems; //Rebind
}

Извинения, если это не достаточно ясно, я чувствовал, что публикация реального кода затруднит понимание из context.

Это решило мою собственную проблему.

Альтернативное решение

См. выше и добавьте элементы без удаления старых. Затем замените весь источник элементов только в событии dropdownopened.

...