C#中将Dictionary绑定到ComboBox的问题
问题:从XML生成Dictionary绑定ComboBox失败
原代码片段
XML文件内容
<configuration> <Paths> <add key="Path_DQM_CE_Prod" value="DQM-CE\DQM_CE_12.2.0_17615\QMConfigurationEditor.exe" /> <add key="Path_DQM_CE_Test" value="DQM-CE\QMConfigurationEditor.exe" /> </Paths> </configuration>
后台代码
public MainWindow() { InitializeComponent(); this.DataContext = this; ///read XML and store into dictionary var xdoc = XDocument.Load(@"\\ServerXYZ\Settings_CAX_Startcenter\config.xml"); var Paths = xdoc.Root.Descendants("Paths").Elements() .ToDictionary(a => (string)a.Attribute("key"), a => (string)a.Attribute("value")); }
XAML代码
<Grid> <StackPanel HorizontalAlignment="Left"> <ComboBox ItemsSource="{Binding Paths}" DisplayMemberPath="Value.Key" /> </StackPanel> </Grid>
问题分析与修复方案
绑定失败的核心原因有两个:
Paths是局部变量,无法被WPF绑定系统访问
WPF的数据绑定要求绑定目标是公共属性,而你当前的Paths是构造函数内的局部变量,绑定引擎找不到这个成员。DisplayMemberPath设置错误
Dictionary的每个元素是KeyValuePair<string, string>类型,其中Key对应XML里的key属性,Value对应XML里的value属性。你写的Value.Key是错误的,应该根据需求选择Key或Value作为显示内容。
修正后的后台代码
// 定义公共属性供绑定使用 public Dictionary<string, string> Paths { get; private set; } public MainWindow() { InitializeComponent(); this.DataContext = this; var xdoc = XDocument.Load(@"\\ServerXYZ\Settings_CAX_Startcenter\config.xml"); // 给公共属性赋值,而非局部变量 Paths = xdoc.Root.Descendants("Paths").Elements() .ToDictionary(a => (string)a.Attribute("key"), a => (string)a.Attribute("value")); }
修正后的XAML代码
如果想显示XML里的key值(比如Path_DQM_CE_Prod):
<Grid> <StackPanel HorizontalAlignment="Left"> <ComboBox ItemsSource="{Binding Paths}" DisplayMemberPath="Key" /> </StackPanel> </Grid>
如果想显示XML里的value值(比如文件路径):
<Grid> <StackPanel HorizontalAlignment="Left"> <ComboBox ItemsSource="{Binding Paths}" DisplayMemberPath="Value" /> </StackPanel> </Grid>
额外优化(可选)
如果后续需要动态更新Paths并让ComboBox自动刷新,建议实现INotifyPropertyChanged接口:
using System.ComponentModel; public partial class MainWindow : Window, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private Dictionary<string, string> _paths; public Dictionary<string, string> Paths { get => _paths; set { _paths = value; OnPropertyChanged(nameof(Paths)); } } public MainWindow() { InitializeComponent(); this.DataContext = this; var xdoc = XDocument.Load(@"\\ServerXYZ\Settings_CAX_Startcenter\config.xml"); Paths = xdoc.Root.Descendants("Paths").Elements() .ToDictionary(a => (string)a.Attribute("key"), a => (string)a.Attribute("value")); } }
内容的提问来源于stack exchange,提问作者Moritz
相关产品推荐
相关产品推荐

