将字典绑定到WPF ListBox

给定dictionary.Values ,你如何绑定dictionary.Values到WPF ListBox,以便项目使用.Name属性?

 struct Drink { public string Name { get; private set; } public int Popularity { get; private set; } public Drink ( string name, int popularity ) : this ( ) { this.Name = name; this.Popularity = popularity; } } 

在items控件上设置ItemsSource会创建对源对象的枚举器的绑定。 Dictionary的枚举器的类型为IEnumerable> 。 因此,在项模板中,您可以绑定到KeyValue属性,并使用路径语法来获取键和值的特定属性。

这是一个例子。 首先是创建和填充字典并将其添加到资源字典的代码(有很多不同的方法可以将字典暴露给数据绑定;这很简单):

 namespace WpfApplication17 { ///  /// Interaction logic for Window1.xaml ///  public partial class Window1 : Window { public Window1() { Dictionary d = new Dictionary(); d.Add("A", new Drink("Nehi", 0)); d.Add("B", new Drink("Moxie", 1)); d.Add("C", new Drink("Vernor's", 2)); d.Add("D", new Drink("Canfield's", 3)); Resources["Drinks"] = d; InitializeComponent(); } public class Drink { public Drink(string name, int popularity) { Name = name; Popularity = popularity; } public string Name { get; set; } public int Popularity { get; set; } } } } 

现在用于填充ListBox的XAML(虽然ListView会更容易,因为您不必定义这个复杂的模板以使其看起来很好):

                     

ListView的XAML要简单得多,并且在启动时显示得更好:

          

要回答您的后续问题:

我推荐Adam Nathan的Windows Presentation Foundation Unleashed 。 有关面板布局的章节解释了Grid如何相当详细地工作。 Grid在很多方面都很反直觉。 您认为您想要创建包含许多项的单个Grid ,但Grid中的行数和列数不是动态的。 因此,您要为每个项创建一个Grid ,然后使用共享大小function来确保每个Grid中的列大小相同。 ListView有自己的怪癖,但对于常见的“在网格中显示多个项目”用例来说,它更直接。

DynamicResource是一个标记扩展,其工作方式与StaticResource非常相似。 不同之处在于,当XAML解析器解析它时解析StaticResource – 如果引用的资源不在资源字典中,则会抛出exception。 如果稍后将项添加到字典中, DynamicResource将解析引用。 这有一点性能成本,但在大多数情况下它可以忽略不计。 如果您使用StaticResource ,我发布的代码可以工作,因为XAML在InitializeComponent被解析。 但我不想记住这一点,所以我默认使用DynamicResource ,如果我绑定到我在代码中添加到资源字典中的东西,只是不要担心它是在创建之前还是之后创建的。 XAML被解析。

至于工具箱:也许我会在VS2010中开始使用它,但是我发现2008年的那个太多了。 反正也不是很有用。 我几乎所有的布局都在编辑器中工作,有些在Kaxaml中。 我认为2008年的可视化编辑器实际上使学习WPF 变得更难 ,因为它在我和XAML(它本身就是我和WPF对象模型之间的抽象层)之间强加了一个抽象层。 它并不是一个非常好的抽象层:决定应该隐藏什么和应该看到什么的设计决策不是,在我看来是正确的。 这也是地狱的错误。

ListBox.DisplayMemberPath = "Name";

这将告诉列表框使用DataContext的“Name”属性