所选项目 属性 对绑定没有反应
Selected item property doesn't react to binding
我已将文本框的文本和组合框的选定项绑定到我的视图模型。组合框中的元素绑定到静态 属性.
<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。没有任何效果,接受设置选定的 index 而不是选定的 item 的方法。可悲的是,我不知道如何才能做到这一点。
我尝试按照建议添加 DisplayMemberPath。那没有用 并且 组合框的项目不再存在。我猜 DisplayMemberPath 指的是从 ItemSource 中提到的任何内容中获取要逐项列出的内容的位置(并且没有 Picked in there).
<ComboBox x:Name="Picky"
ItemsSource="{x:Static local:MainWindow.AllPickables}"
SelectedItem="{Binding CurrentOrder}"
DisplayMemberPath="Picked" ... />
senario 的(几乎)完整源代码
查看主模型分配 window。
<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));
}
}
主要window的隐藏代码(与使用的控件和事件相关的部分)。我的标记中还有一个名为 ThingListing 的网格视图,它在我的视图模型中绑定到 AllThingsView。当我单击其中的一条记录时,触发的事件应该更新 CurrentThing 的值并将选项卡更改为放置绑定控件的选项卡。一切似乎都在正确的地方接受组合框的选定项目。我还有一个方便的扩展方法 Get。它会做你直觉上认为会做的事(一直来回测试)。
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));
}
}
对于 WPF 中的 ComboBox
,在 IEnumerable<PickType> AllPickables
和 XAML 中,必须将 SelectedItem
设置为存在于 ItemsSource
中的对象ItemSource
必须位于 之前 SelectedItem
(因为你已经有了)
当 ComboBox
看到 SelectedItem
时,它必须存在于它的 Items
中。此规则也适用于稍后时间,即当 NotifyPropertyChanged
触发时。
进一步:CurrentThing
应该有相同的类型PickType
public PickType CurrentThing { ... }
和 CurrentThing
应该指向 AllPickables
中的一个现有成员(或者设置为 null 表示不选择)。
看起来在读取视图模型时比较失败。这可能是因为 incorrect/missing 比较方法的实施。尝试实施 Equals 和 GetHash,看看它是否有效。
public override bool Equals(Object input)
{
return Id == ((Thing)input)?.Id;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
我已将文本框的文本和组合框的选定项绑定到我的视图模型。组合框中的元素绑定到静态 属性.
<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。没有任何效果,接受设置选定的 index 而不是选定的 item 的方法。可悲的是,我不知道如何才能做到这一点。
我尝试按照建议添加 DisplayMemberPath。那没有用 并且 组合框的项目不再存在。我猜 DisplayMemberPath 指的是从 ItemSource 中提到的任何内容中获取要逐项列出的内容的位置(并且没有 Picked in there).
<ComboBox x:Name="Picky"
ItemsSource="{x:Static local:MainWindow.AllPickables}"
SelectedItem="{Binding CurrentOrder}"
DisplayMemberPath="Picked" ... />
senario 的(几乎)完整源代码
查看主模型分配 window。
<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));
}
}
主要window的隐藏代码(与使用的控件和事件相关的部分)。我的标记中还有一个名为 ThingListing 的网格视图,它在我的视图模型中绑定到 AllThingsView。当我单击其中的一条记录时,触发的事件应该更新 CurrentThing 的值并将选项卡更改为放置绑定控件的选项卡。一切似乎都在正确的地方接受组合框的选定项目。我还有一个方便的扩展方法 Get。它会做你直觉上认为会做的事(一直来回测试)。
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));
}
}
对于 WPF 中的 ComboBox
,在 IEnumerable<PickType> AllPickables
和 XAML 中,必须将 SelectedItem
设置为存在于 ItemsSource
中的对象ItemSource
必须位于 之前 SelectedItem
(因为你已经有了)
当 ComboBox
看到 SelectedItem
时,它必须存在于它的 Items
中。此规则也适用于稍后时间,即当 NotifyPropertyChanged
触发时。
进一步:CurrentThing
应该有相同的类型PickType
public PickType CurrentThing { ... }
和 CurrentThing
应该指向 AllPickables
中的一个现有成员(或者设置为 null 表示不选择)。
看起来在读取视图模型时比较失败。这可能是因为 incorrect/missing 比较方法的实施。尝试实施 Equals 和 GetHash,看看它是否有效。
public override bool Equals(Object input)
{
return Id == ((Thing)input)?.Id;
}
public override int GetHashCode()
{
return base.GetHashCode();
}