将 ObservableDictionary 绑定到 ComboBox (WPF)
Binding ObservableDictionary to ComboBox (WPF)
我原以为这个问题已经有人回答了,但我没有找到。我有一个简单的 class:
public class BinanceEndpoint : ObservableObject
{
private string baseAddress;
private string socketBaseAddress;
public string BaseAddress
{
get { return baseAddress; }
set { baseAddress = value; RaisePropertyChangedEvent(nameof(BaseAddress)); }
}
public string SocketBaseAddress
{
get { return socketBaseAddress; }
set { socketBaseAddress = value; RaisePropertyChangedEvent(nameof(SocketBaseAddress)); }
}
}
然后我用 class:
中的对象填充 ObservableDictionary
private MainViewModel()
{
private BinanceEndpoint apiEndPoint;
private ObservableDictionary<string, BinanceEndpoint> endPoints = new ObservableDictionary<string, BinanceEndpoint>();
endPoints.Add("Binance.com", new BinanceEndpoint() { BaseAddress = "https://api.binance.com", SocketBaseAddress = "wss://stream.binance.com:9443", });
endPoints.Add("Binance.us", new BinanceEndpoint() { BaseAddress =
"https://api.binance.us", SocketBaseAddress = "wss://stream.binance.us:9443", });
endPoints.Add("Testnet", new BinanceEndpoint() { BaseAddress = "https://testnet.binance.vision", SocketBaseAddress = "wss://testnet.binance.vision", });
}
[JsonIgnore]
public ObservableDictionary<string,BinanceEndpoint> EndPoints
{
get { return endPoints; }
set { endPoints = value; RaisePropertyChangedEvent(nameof(EndPoints)); }
}
public BinanceEndpoint APIEndPoint
{
get { return apiEndPoint; }
set { apiEndPoint = value; RaisePropertyChangedEvent(nameof(APIEndPoint)); }
}
}
然后我尝试使用 ObservableDictionary 填充 ComboBox。
<ComboBox Grid.Column="1" ItemsSource="{Binding EndPoints}" DisplayMemberPath="Key" SelectedValuePath="Value" SelectedValue="{Binding Path=APIEndPoint, Mode=TwoWay}"/>
我遇到的问题是 SelectedValue 在加载时没有更新 ComboBox 的值。我做错了什么?
您应该首先避免绑定到 Dictionary
。 .NET 库中没有 ObservableDictionary 是有原因的 - 自 2002 年发布之年起。我想我们同意这不是因为 MS 开发人员在这么多年后不知道如何实现这样的字典。
您使用的 SelectedValuePath
和 SelectedValue
有误。 SelectedValue
returns SelectedValuePath
指向的 属性 的值。 SelectedValuePath
在 SelectedItem
.
上提供 属性 路径
当您主动设置 SelectedValue
时,控件将尝试查找 select 由 SelectedValuePath
指定的项目的 属性 与 SelectedValue
的值相匹配的项目.
当 SelectedItem
return 是 selected 项目(实例)时,SelectedValue
return 是 属性 的值在使用 SelectedValuePath
.
指定的 SelectedItem
上
例如:我们绑定到一个Dictionary<string, BinanceEndpoint>
。要显示 Dictionary
的 Key
,我们指定 DisplayMemberPath
(作为 DataTemplate
的替代)。
SelectedItem
将保持 KeyValuePair<string, BinanceEndpoint>
.
要获得 ComboBox.SelectedValue
return selected 项的 SocketBaseAddress
值,我们必须将 SelectedValuePath
设置为 "Value.SocketBaseAddress"
:
<ComboBox x:Name="ComboBox"
ItemsSource="{Binding EndPoints}"
DisplayMemberPath="Key"
SelectedValuePath="Value.SocketBaseAddress" />
<!-- Display the selected item's SocketBaseAddress value -->
<TextBlock text="{Binding ElementName=ComboBox, Path=SelectedValue}" />
如果您希望 SelectedValue
到 return BinanceEndpoint
实例,则将 SelectedValuePath
设置为 "Value"
:
<ComboBox x:Name="ComboBox"
ItemsSource="{Binding EndPoints}"
DisplayMemberPath="Key"
SelectedValuePath="Value" />
<!-- Display the selected item's 'SocketBaseAddress' value -->
<TextBlock text="{Binding ElementName=ComboBox, Path=SelectedValue.SocketBaseAddress}" />
我原以为这个问题已经有人回答了,但我没有找到。我有一个简单的 class:
public class BinanceEndpoint : ObservableObject
{
private string baseAddress;
private string socketBaseAddress;
public string BaseAddress
{
get { return baseAddress; }
set { baseAddress = value; RaisePropertyChangedEvent(nameof(BaseAddress)); }
}
public string SocketBaseAddress
{
get { return socketBaseAddress; }
set { socketBaseAddress = value; RaisePropertyChangedEvent(nameof(SocketBaseAddress)); }
}
}
然后我用 class:
中的对象填充 ObservableDictionary private MainViewModel()
{
private BinanceEndpoint apiEndPoint;
private ObservableDictionary<string, BinanceEndpoint> endPoints = new ObservableDictionary<string, BinanceEndpoint>();
endPoints.Add("Binance.com", new BinanceEndpoint() { BaseAddress = "https://api.binance.com", SocketBaseAddress = "wss://stream.binance.com:9443", });
endPoints.Add("Binance.us", new BinanceEndpoint() { BaseAddress =
"https://api.binance.us", SocketBaseAddress = "wss://stream.binance.us:9443", });
endPoints.Add("Testnet", new BinanceEndpoint() { BaseAddress = "https://testnet.binance.vision", SocketBaseAddress = "wss://testnet.binance.vision", });
}
[JsonIgnore]
public ObservableDictionary<string,BinanceEndpoint> EndPoints
{
get { return endPoints; }
set { endPoints = value; RaisePropertyChangedEvent(nameof(EndPoints)); }
}
public BinanceEndpoint APIEndPoint
{
get { return apiEndPoint; }
set { apiEndPoint = value; RaisePropertyChangedEvent(nameof(APIEndPoint)); }
}
}
然后我尝试使用 ObservableDictionary 填充 ComboBox。
<ComboBox Grid.Column="1" ItemsSource="{Binding EndPoints}" DisplayMemberPath="Key" SelectedValuePath="Value" SelectedValue="{Binding Path=APIEndPoint, Mode=TwoWay}"/>
我遇到的问题是 SelectedValue 在加载时没有更新 ComboBox 的值。我做错了什么?
您应该首先避免绑定到 Dictionary
。 .NET 库中没有 ObservableDictionary 是有原因的 - 自 2002 年发布之年起。我想我们同意这不是因为 MS 开发人员在这么多年后不知道如何实现这样的字典。
您使用的 SelectedValuePath
和 SelectedValue
有误。 SelectedValue
returns SelectedValuePath
指向的 属性 的值。 SelectedValuePath
在 SelectedItem
.
上提供 属性 路径
当您主动设置 SelectedValue
时,控件将尝试查找 select 由 SelectedValuePath
指定的项目的 属性 与 SelectedValue
的值相匹配的项目.
当 SelectedItem
return 是 selected 项目(实例)时,SelectedValue
return 是 属性 的值在使用 SelectedValuePath
.
SelectedItem
上
例如:我们绑定到一个Dictionary<string, BinanceEndpoint>
。要显示 Dictionary
的 Key
,我们指定 DisplayMemberPath
(作为 DataTemplate
的替代)。
SelectedItem
将保持 KeyValuePair<string, BinanceEndpoint>
.
要获得 ComboBox.SelectedValue
return selected 项的 SocketBaseAddress
值,我们必须将 SelectedValuePath
设置为 "Value.SocketBaseAddress"
:
<ComboBox x:Name="ComboBox"
ItemsSource="{Binding EndPoints}"
DisplayMemberPath="Key"
SelectedValuePath="Value.SocketBaseAddress" />
<!-- Display the selected item's SocketBaseAddress value -->
<TextBlock text="{Binding ElementName=ComboBox, Path=SelectedValue}" />
如果您希望 SelectedValue
到 return BinanceEndpoint
实例,则将 SelectedValuePath
设置为 "Value"
:
<ComboBox x:Name="ComboBox"
ItemsSource="{Binding EndPoints}"
DisplayMemberPath="Key"
SelectedValuePath="Value" />
<!-- Display the selected item's 'SocketBaseAddress' value -->
<TextBlock text="{Binding ElementName=ComboBox, Path=SelectedValue.SocketBaseAddress}" />