我尽可能地简化了这个问题.基本上我覆盖了组合框的"空"值.因此,如果选中的项目被删除,它将恢复为"(null)".不幸的是,这种行为是错误的,我点击删除,ObservableCollection项被删除,因此更新了属性绑定,并按预期返回"(null)"项.但组合框外观显示空白.然而它所约束的价值是正确的......这个问题可以用下面的代码再现.
要重现此问题,请选择一个项目,然后单击"删除".请注意,此时将调用以下行(当您删除所选项目时).所以它是断点的好地方.
if (m_Selected == null)
{
return Items[0]; //items 0 is ItemNull
}
Run Code Online (Sandbox Code Playgroud)
另请注意,我已经通过在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>
Run Code Online (Sandbox Code Playgroud)
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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果:

你在那里发现了一个很好的绑定问题。但一如既往,这是我们的错,而不是他们的错:)
问题是(是),使用DisplayMemberPathwith SelectedItem。在DisplayMemberPath不给AF ***有关改变的SelectedItem。
要解决此问题,您必须做的有两件事:
首先,在RemoveSelected方法中,将Selected属性设置为 null(强制更新绑定):
public void RemoveSelected()
{
Items.Remove(Selected);
Selected = null;
}
Run Code Online (Sandbox Code Playgroud)
然后,在 XAML 定义中,更改绑定属性:
<ComboBox ItemsSource="{Binding Items}"
SelectedValue="{Binding Selected, Mode=TwoWay}"
DisplayMemberPath="Name"/>
Run Code Online (Sandbox Code Playgroud)
绑定该SelectedValue属性将正确更新ComboBox.
| 归档时间: |
|
| 查看次数: |
2176 次 |
| 最近记录: |