具有集合视图项目源的组合框不会在模型更改时更新选择框项目

发布于 2024-08-30 07:40:19 字数 1048 浏览 16 评论 0原文

对之前的冗长帖子表示歉意。这是我的简洁(!)描述。

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

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

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

为什么会出现这个问题?

仅供参考:

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

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

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

  4. 我尝试通过将 SelectedEmployeeId 设置为 0(它正确地从 itemsSource 选择虚拟“-- Select All --”员工条目)和旧的选定值来刷新 SelectedEmployeeId。但没有用。旧的值让我回到旧的标签。不过,项目集合具有最新条目。

  5. 当我在视图刷新之前和刷新之后设置组合框的 IsEditable=True 时,我会设置 IsEditable=False ,那么事情就会正确进行!

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

谢谢维尼特

·桑赫

Sorry for the earlier lengthy post. Here is my concise (!) description.

I bind a collection view to a combobox as a itemsSource and also bind its selectedvalue with a property from my view model. I must keep IsSynchronizedWithCurrentItem="False".

I change the source list ofr the view and then refresh the view. The changed (added, removed, edited) items appear correctly in the item list of the combo. But problem is with the selected item. When I change its property which is also the displaymember path of the combo, the changed property value does not reflect back on the selecton box of the combo. If you open the combo dropdown it appears correctly on the item list but not on the selection box.

Now if I change the combobox tag to Listbox in my XAML (keeping all attributes as it is) then when selected item's displaymember property value is updated, the changes reflect back on the selected item of the list box .

Why this issue?

Just FYI:

  1. My View Model has properties EmployeeCollectionView and SelectedEmployeeId which are bound to combo as ItemsSource and SelectedValue resp. This VM implements the INotifyPropertyChanged interface.

  2. My core employee class (list of which is the source for the EmployeeCollectionView) is simply a Model class without INotifyPropertyChanged.

  3. DisplayMemberPath is "Name" property of employee Model class. I change this by some means and expect the combo selection box to update the value.

  4. I tried refreshing ther SelectedEmployeeId by setting it 0 (where it correctly selects the dummy "-- Select All --" employee entry from itemsSource) and old selected value back. But no use. The old value takes me back to the old label. Items collection has latest entry though.

  5. When I make combobox's IsEditable=True before the view's refresh and after refresh I make IsEditable=False then the things work out correctly!

But this is a patch and is unnecessary.

Thx

Vinit Sankhe

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

咿呀咿呀哟 2024-09-06 07:40:19

你的第二点和第三点就是为什么这不起作用。当 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();
    }

}

Your points #2 and #3 are why this isn't working. When the ComboBox has an item selected, it displays in the box the Employee.Name property. You state in #2 that Employee does not implement INotifyPropertyChanged and in #3 you are changing Name and expecting it to update in the ComboBox. But the ComboBox has no idea that the property changed so its displayed value will not change.

I've put together a very simple example that will demonstrate. If you comment out the PropertyChanged event you'll notice that clicking the button no longer has an effect on the 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>

And the code behind...

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

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文