2017-01-09 1 views
3

Ich habe ein Kombinationsfeld, das den Objekttyp ändert. Wenn ein neuer Typ ausgewählt wird, zerstöre ich das alte Ansichtsmodell und binde an das neue Ansichtsmodell. Wenn ich das tue, aktualisiert das Kombinationsfeld die ausgewählte Elementeigenschaft nicht mehr.WPF Combobox verliert die Bindung an SelectedItem beim Ändern des Ansichtsmodells

Die Combo-Box-Deklaration sieht so aus. Beachten Sie, dass sich diese Combobox in der ItemTemplate eines ListView befindet.

<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> 

Die Eigenschaft, die ihre Bindung verliert, sieht so aus. Beachten Sie, dass OnPropertyChanged nicht aufgerufen wird, da die Klasse das Fody.PropertyChanged-Paket verwendet und die Klasse mit [ImplementsPropertyChanged] markiert ist.

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

      _type = value; 

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

Der Typ geändert Callback sieht so aus.

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; 
    } 

Das erste Mal, wenn ich den Typ des Objekts ändere, wird das Viewmodel korrekt aktualisiert. Danach ruft das Ändern des ausgewählten Elements der Combobox nicht einmal die Set-Funktion der Eigenschaft auf. Irgendwie behält die Combobox ihre alte Bindung bei.

Der DataContext meiner Sicht wird einmalig beim Start des Programms in Code hinterher zugewiesen. Der Kontext selbst ist eine Singleton-Manager-Klasse, die das tatsächliche Austauschen der Ansichtsmodelle durchführt. Die Initialisierung sieht so aus. Es wird nicht anderweitig aktualisiert.

public MainWindow() 
    { 
     InitializeComponent(); 

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

Die MyViewModels Eigenschaft wird in der Managerklasse als ObservableCollection erklärt wie folgt:

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

Ich habe eine Testanwendung in Visual Studio erstellt 2015 eine Verbindung zum Repository hier. https://github.com/df424/WFPComboBoxTest

+1

Wie stellen Sie den 'DataContext' Ihrer Ansicht ein? Bitte stellen Sie uns eine [mcve] zur Verfügung. – dymanoid

+0

Ich habe den Beitrag so geändert, dass er Informationen darüber enthält, wo der DataContext festgelegt ist. – ghost

+0

bitte posten MyViewModels Eigenschaft –

Antwort

0

zu Enum-Datenquellen binden zuerst mit den folgenden

<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> 

dann das Ressourcenverzeichnis zu Ihrem Fenster hinzufügen oder App

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

Und schließlich fügen Sie Ihre ComboBox Bindung einen Resource hinzufügen, wie

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

Die ViewModel-Eigenschaft sho Im Grunde genommen ist es so etwas wie das Folgende.

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

Hi bic, Vielen Dank für Ihre Antwort. Die Enumeration wird wie gewünscht in der Auswahlliste angezeigt. Es gibt auch kein Problem, das den aktuellen Zustand der Immobilie widerspiegelt. Das Problem tritt auf, wenn ich die Ansichtsmodelle wechsle. Sobald dies erfolgt ist, wird durch einen neuen Wert in der Combobox nicht mehr die set-Funktion der Type-Eigenschaft aufgerufen. Interessanterweise gibt es andere Eigenschaften in der Klasse, die ich nicht aufgenommen habe und die immer noch korrekt aktualisiert werden. – ghost