具有集合视图itemssource的Combobox不会更新模型更改时的选择框项

时间:2010-04-29 02:21:40

标签: mvvm combobox selectedvalue collectionview

对于较早的冗长帖子感到抱歉。这是我的简明(!)描述。

我将一个集合视图绑定到一个组合框作为itemsSource,并将其selectedvalue与我视图模型中的属性绑定。我必须保持IsSynchronizedWithCurrentItem =“False”。

我更改了视图的源列表,然后刷新视图。已更改(添加,删除,已编辑)的项目正确显示在组合的项目列表中。但问题在于所选项目。当我更改其属性(也是组合的显示成员路径)时,更改的属性值不会反映在组合的selecton框中。如果您打开组合下拉列表,它会在项目列表中正确显示,但不会出现在选择框中。

现在,如果我在我的XAML中将组合框标签更改为Listbox(保持所有属性不变),那么当更新所选项目的displaymember属性值时,更改将反映在列表框的选定项目上。

为什么会出现这个问题?

仅供参考:

  1. 我的视图模型具有属性EmployeeCollectionView和SelectedEmployeeId,它们作为ItemsSource和SelectedValue resp绑定到组合。此VM实现INotifyPropertyChanged接口。

  2. 我的核心员工类(其列表是EmployeeCollectionView的源代码)只是一个没有INotifyPropertyChanged的Model类。

  3. DisplayMemberPath是员工Model类的“Name”属性。我通过某种方式更改此值,并期望组合选择框更新值。

  4. 我尝试刷新了SelectedEmployeeId,方法是将其设置为0(正确选择虚拟“ - 全部 - 来自itemsSource的员工条目”)和旧的选定值。但没用。旧的价值把我带回旧标签。物品收藏有最新的条目。

  5. 当我在视图刷新之前制作组合框的IsEditable = True并且在刷新之后我使IsEditable = False然后事情正常运行!

  6. 但这是补丁而且没必要。

    THX

    Vinit Sankhe

1 个答案:

答案 0 :(得分:0)

你的观点#2和#3是不起作用的原因。当ComboBox选择了一个项目时,它会在框中显示Employee.Name属性。您在#2中声明Employee没有实现INotifyPropertyChanged,而在#3中您正在更改Name并期望它在ComboBox中更新。但是ComboBox并不知道该属性发生了变化,因此它的显示值不会改变。

我已经汇总了一个非常简单的例子,可以证明。如果您注释掉PropertyChanged事件,您会注意到单击该按钮不再对UI产生影响。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        SizeToContent="WidthAndHeight">
    <StackPanel>
        <ComboBox ItemsSource="{Binding}" DisplayMemberPath="Name" SelectedIndex="0" Width="150" Height="25" />
        <Button Content="Change" Width="75" Height="25" Click="button_Click"/>
    </StackPanel>
</Window>

背后的代码......

public partial class MainWindow : Window
{

    private ObservableCollection<Thing> things;
    private Queue<string> words;

    public MainWindow()
    {

        // some dummy data
        string text = "Lorem ipsum dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat sed diam voluptua";
        words = new Queue<string>(text.Split(' '));

        things = new ObservableCollection<Thing>();
        things.Add(new Thing { Name = words.Dequeue() });
        things.Add(new Thing { Name = words.Dequeue() });
        things.Add(new Thing { Name = words.Dequeue() });

        DataContext = things;

        InitializeComponent();

    }

    private void button_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        things[0].Name = words.Dequeue();
    }

}