【问题标题】:Problems data binding Listbox问题数据绑定列表框
【发布时间】:2017-01-16 12:57:15
【问题描述】:

我的问题是如何将数据文件附加到 XAML? 让数据 Name, Images, Age 显示 ListBox。

有一个类Person:

public string Name { get; set; }
public string Images { get; set; }
public string Age { get; set; }

有一个xml文件UsersList (约 100 个用户) xml文件不断编辑

<?xml version="1.0" encoding="utf-8" ?>
<users>
  <user name="Bill Gates">  
    <images>https://pbs.twimg.com/profile_images/558109954561679360/j1f9DiJi.jpeg</images>
    <age>48</age>
  </user>
  <user name="Larry Page">
    <images>http://www.siliconbeat.com/wp-content/uploads/2015/06/page.jpg</images>
    <age>42</age>
  </user>
</users>

XAML

<ListBox  x:Name="ListBox" Margin="36,10,273,0" >
            <ListBox.DataContext>
                <user:Person/>
            </ListBox.DataContext>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" >
                        <Image Source="{Binding Images}" />
                        <TextBlock Text="{Binding Name}" />
                        <TextBlock Text="{Binding Age}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

代码隐藏

public MainWindow()
        {
            InitializeComponent();
            Load();
        }
    public void Load()
        {
            Person user = new Person();
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load("UsersList");

            XmlElement xRoot = xDoc.DocumentElement;

            foreach (XmlNode xnode in xRoot)
            {


                if (xnode.Attributes.Count > 0)
                {
                    XmlNode attr = xnode.Attributes.GetNamedItem("name");
                    if (attr != null)
                        user.Name = attr.Value;

                }

                foreach (XmlNode childnode in xnode.ChildNodes)
                {

                    if (childnode.Name == "images")
                    {
                        user.Images = childnode.InnerText;

                    }

                    if (childnode.Name == "age")
                    {
                        user.Age = childnode.InnerText;
                    }
                }

            }

        }

【问题讨论】:

    标签: c# xml wpf xaml listbox


    【解决方案1】:

    找到下面的代码。

    class MainWindow:System.Windows.Window 
    {
        List<Person> lstPerson;
        public MainWindow()
        {
            InitializeComponent();
            lstPerson = new List<Person>();
            Load();
        }
        public void Load()
        {
    
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load("UsersList");
    
            XmlElement xRoot = xDoc.DocumentElement;
    
            foreach (XmlNode xnode in xRoot)
            {
                Person user = new Person();
    
                if (xnode.Attributes.Count > 0)
                {
                    XmlNode attr = xnode.Attributes.GetNamedItem("name");
                    if (attr != null)
                        user.Name = attr.Value;
    
                }
    
                foreach (XmlNode childnode in xnode.ChildNodes)
                {
    
                    if (childnode.Name == "images")
                    {
                        user.Images = childnode.InnerText;
    
                    }
    
                    if (childnode.Name == "age")
                    {
                        user.Age = childnode.InnerText;
                    }
                }
    
                lstPerson.Add(user)
    
            }
    
            ListBox.itemsSource= lstPerson
    
        }
    }    
    

    下面是 Xaml 部分

    <ListBox  x:Name="ListBox" Margin="36,10,273,0" >            
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" >
                        <Image Source="{Binding Images}" />
                        <TextBlock Text="{Binding Name}" />
                        <TextBlock Text="{Binding Age}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    

    图片源绑定

    您不能提供 http 地址作为图片来源。在这里,您需要一个转换器,它可以从 Web 下载图像创建图像并返回源。

    【讨论】:

      【解决方案2】:

      您应该将 ListBox 的 ItemsSource 属性设置为 IEnumerable&lt;Person&gt;:

      public MainWindow()
      {
          InitializeComponent();
          ListBox.ItemsSource = Load();
      }
      
      public List<Person> Load()
      {
          XmlDocument xDoc = new XmlDocument();
          xDoc.Load("UsersList");
      
          XmlElement xRoot = xDoc.DocumentElement;
      
          List<Person> users = new List<Person>();
          foreach (XmlNode xnode in xRoot)
          {
              Person user = new Person();
              if (xnode.Attributes.Count > 0)
              {
                  XmlNode attr = xnode.Attributes.GetNamedItem("name");
                  if (attr != null)
                      user.Name = attr.Value;
              }
      
              foreach (XmlNode childnode in xnode.ChildNodes)
              {
      
                  if (childnode.Name == "images")
                  {
                      user.Images = childnode.InnerText;
      
                  }
      
                  if (childnode.Name == "age")
                  {
                      user.Age = childnode.InnerText;
                  }
              }
              users.Add(user);
          }
      
          return users;
      }
      

      【讨论】:

        【解决方案3】:

        您需要将您的 ListBox.ItemsSource 设置为可观察的人员列表 (ObservableCollection&lt;Person&gt;),并在您的 Person 类上实现 INotifyPropertyChanged 接口。

        Person user = new Person(); 应该是ObservableCollection&lt;Person&gt; persons = new ObservableCollection&lt;Person&gt;();

        然后你必须在 foreach 循环中创建一个新的Person 对象并将其添加到人员列表中,如下所示:

        persons.Add(person);
        

        如果你改变一个人的属性就不需要更新你的列表,那么你真的不需要实现INotifyPropertyChanged接口。

        【讨论】:

        • 正确的名字是ObservableCollection不是ObservableList,我编辑了我的答案。
        • 其实必须设置ListBox的ItemsSource,而不是DataContext。如果你只设置 DataContext,你还需要ItemsSource="{Binding}" 之类的东西。
        猜你喜欢
        • 2012-05-10
        • 2010-11-22
        • 2011-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多