我尽可能地简化了这个问题。基本上我覆盖了组合框的“空”值。因此,如果选中的项目被删除,它将恢复为“(null)”。不幸的是,这是错误的行为,我点击删除,ObservableCollection项被删除,因此更新了属性绑定,并按预期返回“(null)”项。但组合框外观显示空白。然而它所受的价值是正确的...这个问题可以用下面的代码再现。
要重现此问题,请选择一个项目,然后按“删除”。请注意,此时将调用以下行(当您删除所选项目时)。所以它是断点的好地方。
if (m_Selected == null)
{
return Items[0]; //items 0 is ItemNull
}
另请注意,我已通过在DisplayMemberPath上强制执行属性更新来解决此问题。这没用。
MainWindow.xaml
<Window x:Class="WPFCodeDump.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<ComboBox ItemsSource="{Binding Items}" SelectedItem="{Binding Selected, Mode=TwoWay}" DisplayMemberPath="Name"></ComboBox>
<Button Click="ButtonBase_OnClick">Remove Selected</Button>
</StackPanel>
</Window>
MainWindowViewModel.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
namespace WPFCodeDump
{
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
//Item class
public class Item : ViewModelBase
{
public Item(string name)
{
m_Name = name;
}
public string Name
{
get { return m_Name; }
}
private string m_Name;
public void ForcePropertyUpdate()
{
OnPropertyChanged("Name");
}
}
//Item class
public class ItemNull : Item
{
public ItemNull()
: base("(null)")
{
}
}
class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel()
{
m_Items.Add(new ItemNull());
for (int i = 0; i < 10; i++)
{
m_Items.Add(new Item("TestItem" + i));
}
Selected = null;
}
//Remove selected command
public void RemoveSelected()
{
Items.Remove(Selected);
}
//The item list
private ObservableCollection<Item> m_Items = new ObservableCollection<Item>();
public ObservableCollection<Item> Items
{
get { return m_Items; }
}
//Selected item
private Item m_Selected;
public Item Selected
{
get
{
if (m_Selected == null)
{
return Items[0]; //items 0 is ItemNull
}
return m_Selected;
}
set
{
m_Selected = value;
OnPropertyChanged();
if(m_Selected!=null) m_Selected.ForcePropertyUpdate();
}
}
}
}
MainWindow.xaml.cs
using System.Windows;
namespace WPFCodeDump
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
((MainWindowViewModel) DataContext).RemoveSelected();
}
}
}
结果:
答案 0 :(得分:4)
你在那里发现了一个很好的绑定问题。但一如既往,这是我们的错,而不是他们的错误:)。
问题是(是),DisplayMemberPath
与SelectedItem
一起使用。
DisplayMemberPath
并未提供有关已更改SelectedItem
的f ***。
要解决此问题,您需要做的是两件事:
首先,在RemoveSelected
方法中,将Selected
属性设置为null(强制更新绑定):
public void RemoveSelected()
{
Items.Remove(Selected);
Selected = null;
}
然后,在XAML定义中,更改绑定属性:
<ComboBox ItemsSource="{Binding Items}"
SelectedValue="{Binding Selected, Mode=TwoWay}"
DisplayMemberPath="Name"/>
绑定SelectedValue
属性将正确更新ComboBox
中显示的文本。