【问题标题】:WPF Databinding With A Collection Object带有集合对象的 WPF 数据绑定
【发布时间】:2010-05-27 07:13:11
【问题描述】:

我有一个简单的类,定义如下:

public class Person
{
    int _id;
    string _name;

    public Person()
    { }

    public int ID
    {
        get { return _id; }
        set { _id = value; }
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

存储在数据库中,并通过更多代码将其放入 ObservableCollection 对象中,以便稍后尝试在 WPF 中进行数据绑定:

 public class People : ObservableCollection<Person>
{
    public People() : base() { }

    public void Add(List<Person> pListOfPeople)
    {
        foreach (Person p in pListOfPeople) this.Add(p);
    }
}

在 XAML 中,我有一个 ListView,我想在“People”对象中的每个项目从数据库更新时填充一个 ListViewItem(由一个文本块组成)。我还希望该文本块绑定到 Person 对象的“名称”属性。

一开始我以为我可以这样做:

lstPeople.DataContext = objPeople;

其中 lstPeople 是我的 XAML 中的 ListView 控件,但这当然什么都不做。我在网上找到了很多例子,人们通过 XAML 创建一个对象,然后通过他们的 XAML 绑定到它;但不是我们绑定到实例化对象并相应地重新绘制。

有人可以指点一下吗:

A) 如何将 ListView 控件绑定到我实例化的“人物”集合对象?

B) 我如何将模板应用到我的 ListView 以针对集合中的对象对其进行格式化?

即使链接到一个体面的示例(请不要对 XAML 中声明的对象进行操作),我们也将不胜感激。

【问题讨论】:

    标签: wpf data-binding collections


    【解决方案1】:

    你是如此接近。

    lstPeople.ItemsSource = objPeople; // :)
    

    您唯一需要做的另一件事是如何为集合中的每个项目应用视图。没问题。我不会使用 ListView...我只会使用 ItemsControl,因为它更简单一些。

    <ItemsControl x:Name="lstPeople">
        <ItemsControl.ItemTemplate>
             <DataTemplate>
                  <TextBlock Text="{Binding Name}" />
             </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    

    差不多就是这样。 Listview 的策略是相同的,但您只需要提供一点点 XAML 来提供列标题和内容。我现在不能 100% 确定你需要这个,所以我把它省略了。

    编辑:这是“AddRange”的扩展方法,它将通过子类化 ObservableCollection 来完成您尝试做的事情。简单一点...特别是如果你最终有很多集合类型(你会的)

    public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items)
    {
         foreach(var item in items)
         {
              collection.Add(item);
         }
    }
    

    那么你可以这样做:

    ObservableCollection<Person> peeps = new ObservableCollection<Person>();
    peeps.AddRange(new List<Person>
    { 
         new Person() { Name = "Greg" }, 
         new Person() { Name = "Joe" } 
    });
    

    【讨论】:

      【解决方案2】:

      @Anderson 秒杀我,我的回答非常相似。

      我要补充一点:不需要定义从 ObservableCollection 继承的新集合类型,而是您可以这样做:

      ObservableCollection<Person> myPeopleCollection = new ObservableCollection<Person>();
      

      您想要扩展它的唯一时间是,如果您打算做一些不同或喜欢它的事情,而您似乎没有这样做。

      【讨论】:

      • OP 想要一个“AddRange”类型的方法用于他的收藏。我经常在 ObservableCollections 上自己想要这个。我明白你为什么要那样做。我写了 ExtensionMethods 来做同样的事情。
      • @Anderson - 是的,乍一看,我看到的只是 Add 函数,当你提到它时,我再次查看并看到了他传递给它的参数。跨度>
      【解决方案3】:

      确实,“安德森·艾姆斯”的回答是正确的(赞成),尽管我有两点意见:

      首先,如果你只需要显示一个对象的一个​​属性,我认为使用ListBox而不是ListView会更简单更简洁,因为绑定属性的代码会减少到

      <ListBox x:Name="lstPeople" DisplayMemberPath="Name" />
      

      其次,如果您使用 WPF 和 Binding,请确保您的对象实现 INotifyPropertyChanged,以便始终在 UI 和对象之间同步更改。

      public class Person : INotifyPropertyChanged
      {
          int _id;
          string _name;
      
          public Person()
          { }
      
          public int ID
          {
              get { return _id; }
              set { 
                   _id = value; 
                   RaisePropertyChanged("ID");
                  }
          }
      
          public string Name
          {
              get { return _name; }
              set { 
                   _name = value;  
                   RaisePropertyChanged("Name");
                  }
          }
      
          pivate void RaisePropertyChanged(string propName)
          {
              if (PropertyChanged != null)
                  PropertyChanged(this, new PropertyChangedEventArgs(propName));
          }
      
      }
      

      【讨论】:

      • 感谢您的提示;进一步的谷歌搜索让我相信你是对的,我将不得不在我的代码中实现 INotifyPropertyChanged。感谢您的信息!
      猜你喜欢
      • 1970-01-01
      • 2012-07-03
      • 2011-09-02
      • 2013-05-29
      • 2011-05-14
      • 2014-08-25
      • 2011-01-03
      • 1970-01-01
      • 2014-02-15
      相关资源
      最近更新 更多