更改视图模型时,WPF Combobox失去对SelectedItem的绑定

时间:2017-01-09 16:03:43

标签: wpf

我有一个改变对象类型的组合框。选择新类型后,我会销毁旧视图模型并绑定到新视图模型。当我这样做时,组合框不再更新所选的项属性。

组合框声明如下所示。请注意,这个组合框位于ListView的ItemTemplate中。

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

我第一次更改viewmodel正确更新的对象类型。之后,更改组合框的所选项目甚至不会调用属性的Set函数。不知何故,组合框保持其旧的绑定。

我的视图的DataContext在程序开头的代码后面分配了一次。上下文本身是一个单例管理器类,用于执行视图模型的实际交换。初始化看起来像这样。它没有更新。

    public MainWindow()
    {
        InitializeComponent();

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

MyViewModels属性在manager类中声明为observablecollection,如下所示:

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

我在visual studio 2015中创建了一个测试应用程序,这里有一个指向存储库的链接。 https://github.com/df424/WFPComboBoxTest

1 个答案:

答案 0 :(得分: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属性应该基本上类似于以下内容。

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