我已将文本框的文本和组合框的选定项目绑定到我的视图模型。组合框中的元素绑定到静态属性。
<TextBox x:Name="Texty"
Text="{Binding CurrentThing.Texty}" ... />
<ComboBox x:Name="Picky"
ItemsSource="{x:Static local:MainWindow.AllPickables}"
SelectedItem="{Binding CurrentThing.Picked}" ... />
似乎绑定有效,因为文本框接收正确的内容。组合框也正确地在列表中获取它的值。但是,问题在于没有进行选择。
起初我认为它与某些控制器具有 Mode 的另一个默认值这一事实有关,所以我尝试将其明确地设置为组合框的双向。在我看来,行为没有差别。
我能做错什么?如何解决(或至少是故障排除)?
我已经跟踪了我能找到的所有提示,因为所有提示都是more or less the same。没有任何效果,请接受设置所选索引的方法,而不是选择项。可悲的是,我看不出自己能做到这一点。
我已按照建议尝试添加 DisplayMemberPath 。这不起作用和组合框的项目不再存在。我猜测 DisplayMemberPath 指的是从 ItemSource 中引用的内容中逐条列出的内容(并且那里没有 Picked )
<ComboBox x:Name="Picky"
ItemsSource="{x:Static local:MainWindow.AllPickables}"
SelectedItem="{Binding CurrentOrder}"
DisplayMemberPath="Picked" ... />
查看主窗口的模型分配。
<Window.DataContext>
<local:Presenter/>
</Window.DataContext>
使用的视图模型(关于有问题的组件的大小版本,以便成为最小示例)。
public class Presenter : INotifyPropertyChanged
{
private ObservableCollection<Thing> _allThings;
private Thing _currentThing;
public Thing CurrentThing
{
get { return _currentThing; }
set { _currentThing = value; OnPropertyChanged(); }
}
public ListCollectionView AllThingsView { get; set; }
private IEnumerable<PickType> _allPickables;
public IEnumerable<PickType> AllPickables
{
get { return _allPickables; }
set { _allPickables = value; OnPropertyChanged(); }
}
public Presenter()
{
_allThings = new ObservableCollection<Thing>(DataAccessor.GetThings());
AllThingsView = new ListCollectionView(_allThings);
_allPickables = DataAccessor.GetPickables();
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] String name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
后面的主窗口代码(与使用的控件和事件相关的部分)。我的标记中还有一个名为 ThingListing 的网格视图,它在我的视图模型中绑定到 AllThingsView 。当我单击其中的记录时,触发的事件应该更新 CurrentThing 的值,并将选项卡更改为放置绑定控件的选项卡。似乎所有东西都在正确的位置接受组合框的选定项目。我还有一个便利扩展方法获取。它做你直觉认为它会做的事情(永远地来回测试)。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Presenter();
}
private void ThingListing_OnMouseDoubleClick(Object sender, MouseButtonEventArgs eventArgs)
{
DataContext.Get<Presenter>().CurrentThing
= sender.Get<DataGrid>().CurrentItem.Get<Thing>();
Dispatcher.BeginInvoke((Action)(() => tabControl.SelectedIndex = 1));
}
}
答案 0 :(得分:1)
对于WPF中的ComboBox
,必须将SelectedItem
设置为ItemsSource
中IEnumerable<PickType> AllPickables
以及XAML ItemSource
中的对象。定位之前 SelectedItem
(正如您已经拥有的那样)
当ComboBox
看到SelectedItem
时,它必须出现在Items
中。此规则也适用于稍后的时间,即NotifyPropertyChanged
发生时。
此外:CurrentThing
应具有相同的类型PickType
public PickType CurrentThing { ... }
和CurrentThing
指向AllPickables
中的一个现有成员(或者设置为null以进行无选择)。
答案 1 :(得分:1)
在读取视图模型时,看起来比较失败。这可能是因为比较方法的实施不正确/缺失。尝试实现Equals和GetHash,看看它是否有效。
public override bool Equals(Object input)
{
return Id == ((Thing)input)?.Id;
}
public override int GetHashCode()
{
return base.GetHashCode();
}