1

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

我将集合视图作为 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 事情正常进行!

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

谢谢

维尼特·桑赫

4

1 回答 1

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

}
于 2010-04-29T04:03:09.610 回答