ComboBox 绑定到引用的(相对)源
ComboBox binding to referenced (relative) source
将 ComboBox
绑定到引用源时:
<ComboBox SelectedValue="{Binding Source.SelectedItem}"
ItemsSource="{Binding Source.Items}"
DisplayMemberPath="Name" />
其中 Source
是
SourceType _source;
public SourceType Source
{
get { return _source; }
set { _source = value; OnPropertyChanged(); }
}
并且SourceType
是
public class SourceType: INotifyPropertyChanged
{
Item _selectedItem;
public Item SelectedItem
{
get { return _selectedItem; }
set { _selectedItem = value; OnPropertyChanged(); }
}
public IReadOnlyList<Item> Items { get; }
public SourceType(...)
{
Items = new List<Items>(...) // **new** list generated from passed arguments
SelectedItem = Items.First();
}
}
并且Item
是
public class Item: INotifyPropertyChanged
{
string _name;
public string Name
{
get { return _name; }
set { _name = value; OnPropertyChanged(); }
}
}
发生以下情况:
- 只有一个来源(如果
Source
永远不会改变)它有效:ComboBox
显示 Items
的列表并选择了正确的项目(我可以看到它的 Name
切换视图时);
- 对于多个项目
ComboBox
错误:没有选择(但下拉列表存在并且工作正常),切换视图或 Source
更改时选择不会保留(例如,在 2 个来源之间)。
似乎 ComboBox
在识别 SelectedValue
或在 ItemsSource
中找到它时遇到了一些问题。而且我不知道哪里出了问题。
调试没有发现任何问题:Items
设置正确,SelectedItem
是 Items
集合中的 第一个 项,但 ComboBox
显示而无需选择。为什么?
我将对项目使用 ObservableCollection 而不是列表,对组合框使用 SelectedItem,而不是 SelectedValue。
阅读这个关于 SelectedItem 和 SelectedValue 之间差异的好答案
Difference between SelectedItem, SelectedValue and SelectedValuePath
@Giangregorio 的回答很好,而且一般都能正常工作,但现在我记得为什么我首先使用 SelectedValue
。
SelectedValue
在 ItemsSource
不 包含 SelectedValue
时很有用。如果使用 SelectedItem
(根据答案),则绑定将使用 null
调用 setter,就好像用户可以从列表中 select null
一样。我正在利用这种情况(以避免使用数据模板和更复杂的 ViewModel),所以我必须坚持使用 SelectedValue
并且我想我在其他 should-work[ 中找到了问题的原因=35=]案例.
我必须首先声明 ItemsSource
绑定,然后 SelectedValue
第二:
<ComboBox ItemsSource="{Binding Source.Items}"
SelectedValue="{Binding Source.SelectedItem}"
DisplayMemberPath="Name" />
有效!
在我看来像是另一个 xaml 特定问题,类似于 declare CommandParameter before Command
问题。
将 ComboBox
绑定到引用源时:
<ComboBox SelectedValue="{Binding Source.SelectedItem}"
ItemsSource="{Binding Source.Items}"
DisplayMemberPath="Name" />
其中 Source
是
SourceType _source;
public SourceType Source
{
get { return _source; }
set { _source = value; OnPropertyChanged(); }
}
并且SourceType
是
public class SourceType: INotifyPropertyChanged
{
Item _selectedItem;
public Item SelectedItem
{
get { return _selectedItem; }
set { _selectedItem = value; OnPropertyChanged(); }
}
public IReadOnlyList<Item> Items { get; }
public SourceType(...)
{
Items = new List<Items>(...) // **new** list generated from passed arguments
SelectedItem = Items.First();
}
}
并且Item
是
public class Item: INotifyPropertyChanged
{
string _name;
public string Name
{
get { return _name; }
set { _name = value; OnPropertyChanged(); }
}
}
发生以下情况:
- 只有一个来源(如果
Source
永远不会改变)它有效:ComboBox
显示Items
的列表并选择了正确的项目(我可以看到它的Name
切换视图时); - 对于多个项目
ComboBox
错误:没有选择(但下拉列表存在并且工作正常),切换视图或Source
更改时选择不会保留(例如,在 2 个来源之间)。
似乎 ComboBox
在识别 SelectedValue
或在 ItemsSource
中找到它时遇到了一些问题。而且我不知道哪里出了问题。
调试没有发现任何问题:Items
设置正确,SelectedItem
是 Items
集合中的 第一个 项,但 ComboBox
显示而无需选择。为什么?
我将对项目使用 ObservableCollection 而不是列表,对组合框使用 SelectedItem,而不是 SelectedValue。
阅读这个关于 SelectedItem 和 SelectedValue 之间差异的好答案 Difference between SelectedItem, SelectedValue and SelectedValuePath
@Giangregorio 的回答很好,而且一般都能正常工作,但现在我记得为什么我首先使用 SelectedValue
。
SelectedValue
在 ItemsSource
不 包含 SelectedValue
时很有用。如果使用 SelectedItem
(根据答案),则绑定将使用 null
调用 setter,就好像用户可以从列表中 select null
一样。我正在利用这种情况(以避免使用数据模板和更复杂的 ViewModel),所以我必须坚持使用 SelectedValue
并且我想我在其他 should-work[ 中找到了问题的原因=35=]案例.
我必须首先声明 ItemsSource
绑定,然后 SelectedValue
第二:
<ComboBox ItemsSource="{Binding Source.Items}"
SelectedValue="{Binding Source.SelectedItem}"
DisplayMemberPath="Name" />
有效!
在我看来像是另一个 xaml 特定问题,类似于 declare CommandParameter before Command
问题。