2017-01-09 2 views
3

У меня есть поле со списком, которое изменяет тип объектов. Когда выбран новый тип, я уничтожаю старую модель представления и привязываюсь к новой модели представления. Когда я делаю это, поле со списком больше не обновляет свойство выбранного элемента.WPF Combobox теряет привязку к SelectedItem при смене вида модели

Объявление в виде комбинированного окна выглядит следующим образом. Обратите внимание, что это поле со списком находится в ItemTemplate ListView.

<ListView ItemSource="{Binding MyViewModels}"> 
    <ListView.ItemTemplate> 
     <DataTemplate DataType="viewModels:MyTypeViewModel"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="Type:" Width="170"/> 
       <ComboBox SelectedItem="{Binding Type}" 
              ItemsSource="{Binding Source={StaticResource MyEnumTypes}}" 
              Width="150"/> 
      </StackPanel> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

Свойство, которое теряет привязку, выглядит следующим образом. Обратите внимание, что я не вызываю OnPropertyChanged, потому что класс использует пакет Fody.PropertyChanged, а класс помечен как [ImplementsPropertyChanged].

public MyType Type { get; set; } 
    { 
     get { return _type; } 
     set 
     { 
      if (_type == value) return; 

      _type = value; 

      OnMyTypeChanged?.Invoke(this, new MyTypeChangedEventArgs(_type)); 
     } 
    } 

Тип измененного обратного вызова выглядит следующим образом.

private void OnMyTypeChanged(object sender, MyTypeChangedEventArgs args) 
    { 
     var index = MyViewModels.IndexOf(sender as MyViewModel); 

     var selected = SelectedMyViewModel == MyViewModels[index]; 

     var tmp = CreateReplacementViewModelByType(args.Type, MyViewModels[index].Model.Address); 

     if (selected) 
      SelectedMyViewModel = tmp; 

     MyViewModels[index] = tmp; 

     MyViewModels[index].OnMyTypeChanged += OnMyTypeChanged; 
    } 

В первый раз, когда я изменяю тип объекта, система просмотра обновляется правильно. После этого изменение выбранного элемента combobox даже не вызывает функцию Set свойства. Каким-то образом combobox сохраняет свою старую привязку.

DataContext моего представления присваивается один раз в начале программы позади кода. Сам контекст представляет собой одноуровневый менеджерский класс, который выполняет фактическую замену моделей представления. Инициализация выглядит так. В противном случае он не обновляется.

public MainWindow() 
    { 
     InitializeComponent(); 

     //Set the global DataContext 
     DataContext = MyTypeManager.Instance; 
    } 

В MyViewModels свойство объявляется в классе менеджера как ObservableCollection следующим образом:

public ObservableCollection<MyViewModel> MyViewModels { get; } = new ObservableCollection<MyViewModel>(); 

Я создал тестовое приложение в визуальной студии 2015 ссылка на хранилище находится здесь. https://github.com/df424/WFPComboBoxTest

+1

Как вы устанавливаете 'DataContext' вашего представления? Пожалуйста, предоставьте нам [mcve]. – dymanoid

+0

Я изменил сообщение, чтобы включить информацию о том, где установлен DataContext. – ghost

+0

пожалуйста, опубликуйте свойство MyViewModels –

ответ

0

Для привязки к Enum источникам данных первым добавить ResourceDictionary со следующим

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    xmlns:utility="clr-namespace:MyApp;assembly=MyApp"> 
    <ObjectDataProvider x:Key="MyEnumTypesSource" MethodName="GetValues" ObjectType="{x:Type sys:Enum}"> 
    <ObjectDataProvider.MethodParameters> 
     <x:Type TypeName="MyApp:MyEnumTypes" /> 
    </ObjectDataProvider.MethodParameters> 
    </ObjectDataProvider> 
</ResourceDictionary> 

Затем добавьте словарь ресурсов в окно или приложение

<Window.Resources> 
    <ResourceDictionary> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="/Resources/EnumDataSources.xaml" /> 
    </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Window.Resources> 

И, наконец, добавить ComboBox связывание следующим

<ComboBox Height="24" Width="100" ItemsSource="{Binding Source={StaticResource MyEnumTypesSource}}" 
    SelectedValue="{Binding MyViewModel.MyCurrentEnumValue}" /> 

ViewModel недвижимость sho uld просто в основном что-то вроде следующего.

public MyApp.MyEnumTypes MyCurrentEnumValue 
{ 
    get { return m_MyCurrentEnumValue; } 
    set 
    { 
     m_MyCurrentEnumValue = value; 
     OnPropertyChanged("MyCurrentEnumValue"); 
    } 
} 
+0

Привет, спасибо, за ваш ответ. Перечисление отображается как опция в поле со списком, как предполагалось. Также нет проблем, отражающих текущее состояние собственности. Проблема возникает, когда я переключаю модели просмотра. Как только это будет сделано, выбор нового значения в поле со списком больше не вызывает вызов функции set свойства Type. Интересно, что в классе, который я не включил, есть другие свойства, которые по-прежнему обновляются правильно. – ghost

Смежные вопросы