【问题标题】:Combobox with collection view itemssource does not update selection box item on changes to the Model具有集合视图项目源的组合框不会在模型更改时更新选择框项目
【发布时间】:2011-02-13 15:11:13
【问题描述】:

很抱歉之前的冗长帖子。这是我的简明 (!) 描述。

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

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

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

为什么会出现这个问题?

仅供参考:

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

  2. 我的核心员工类(其中的列表是 EmployeeCollectionView 的源)只是一个没有 INotifyPropertyChanged 的​​模型类。

  3. DisplayMemberPath 是员工模型类的“名称”属性。我通过某种方式对此进行了更改,并希望组合选择框能够更新该值。

  4. 我尝试通过将 SelectedEmployeeId 设置为 0(它正确地从 itemsSource 中选择虚拟“-- 全选-”员工条目)来刷新 SelectedEmployeeId 并返回旧的选定值。但是没有用。旧值带我回到旧标签。物品集合有最新条目。

  5. 当我在视图刷新之前设置组合框的 IsEditable=True 并在刷新之后设置 IsEditable=False 时,一切正常!

但这是一个补丁,没有必要。

谢谢

维尼特·桑赫

【问题讨论】:

    标签: mvvm combobox selectedvalue collectionview


    【解决方案1】:

    您的第 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();
        }
    
    }
    

    【讨论】:

    • 嗨乔希,谢谢你的回答,但为什么这对 ListBox 有效。 ListBox 的选定项正确显示更新的名称(没有 INotify 接口)。据我所知,在 MVVM 中,不建议核心模型类(在我的例子中是员工类)具有 INotifyPropertyChanged。只有 ViewModel 实现了这个接口。
    • 没有看到代码,我很难说出 ListBox 为何有效。但是你对 MVVM 的理解不一定是错误的,但是 MVVM 还是比较新的,并没有什么硬性规定。事实是,在 MVVM 中,您不应该直接在 UI 中公开“模型”类,但每个人都会不时违反该规则。但是,如果您希望对绑定成员的更改反映在 UI 中,您必须实现 INotifyPropertyChanged。
    猜你喜欢
    • 1970-01-01
    • 2019-04-21
    • 2011-08-17
    • 2016-06-12
    • 2015-09-30
    • 2012-11-27
    • 1970-01-01
    • 2012-01-30
    相关资源
    最近更新 更多