【问题标题】:Why ui update when binding ItemsSource in xaml but doesn't when assigning it in code?为什么在 xaml 中绑定 ItemsSource 时 ui 更新但在代码中分配它时不更新?
【发布时间】:2020-04-06 11:01:00
【问题描述】:

我正在尝试将具有DataTemplatecombobox 绑定到由静态方法Populate() 生成的类列表。

在分配combo1.ItemsSource = Peoplelist; 代码隐藏时,ui 中的combobox 项目正在更新,但是当我在xaml 中进行绑定时:ItemsSource="{Binding Path=Peoplelist}" 不是。我错过了什么?

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Windows;

namespace WpfTest
{
    public partial class MainWindow : Window
    {
        public List<People> Peoplelist;

        public MainWindow()
        {
            Peoplelist = new List<People>();
            People.Populate(Peoplelist);

            InitializeComponent();
            //combo1.ItemsSource = Peoplelist;  //working
        }
    }


    public class People
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public People() { }

        public People(String _FirstName, String _FamilyName)
        {
            FirstName = _FirstName;
            LastName = _FamilyName;
        }

        public static void Populate(List<People> lst)
        {
            lst.Add(new People
            {
                FirstName = "Jon",
                LastName = "Jonathan",
            });
            lst.Add(new People
            {
                FirstName = "Mark",
                LastName = "Markthan",
            });
            lst.Add(new People
            {
                FirstName = "Spence",
                LastName = "Spencer",
            });
        }
    }
}

MainWindow.xaml

<Window x:Class="WpfTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
           mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ComboBox Name="combo1" VerticalAlignment="Center" HorizontalAlignment="Center" MinWidth="200" 
          SelectedValuePath="LastName" ItemsSource="{Binding Path=Peoplelist}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding FirstName}"/>
                        <TextBlock Text="--"/>
                        <TextBlock Text="{Binding LastName}"/>
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </Grid>
</Window>

【问题讨论】:

  • 注意combo1.ItemsSource = Peoplelist;不是绑定,只是一个普通的赋值。
  • 更好的使用接口INotifyPropertyChanged。会让生活更轻松。 docs.microsoft.com/en-us/dotnet/api/…

标签: c# wpf xaml data-binding


【解决方案1】:

您的代码有两个问题。 首先:您没有在您的 xaml 或代码中指定数据上下文,因此它不知道您要绑定到的数据在哪里。 第二:您的 Peoplelist 应该是一个属性,因为 WPF 数据绑定仅适用于公共属性。

所以你的 MainWindow 类应该是

public partial class MainWindow : Window
{
    public List<People> Peoplelist { get; set; }

    public MainWindow()
    {
        Peoplelist = new List<People>();
        People.Populate(Peoplelist);
        DataContext = this;
        InitializeComponent();
    }
}

【讨论】:

  • Peoplelist 也应该是只读属性。否则它应该触发更改通知。声明为public List&lt;People&gt; Peoplelist { get; } = new List&lt;People&gt;();
  • 或者更好的public ObservableCollection&lt;People&gt; Peoplelist { get; } = new ObservableCollection&lt;People&gt;(); 以便以后添加或删除元素更新 UI。
  • 你说得对。对不起,我忘了提。它避开了我,因为我寻找了修改代码最少的方法。
  • @Clemens 谢谢你,你说它必须灵活,当然我也必须改变填充方法:public static void Populate(ObservableCollection&lt;People&gt; lst)
  • @johan472 更灵活:public static void Populate(ICollection&lt;People&gt; lst)
猜你喜欢
  • 2018-06-28
  • 2023-03-09
  • 1970-01-01
  • 2011-10-26
  • 1970-01-01
  • 2016-08-07
  • 2013-10-09
  • 1970-01-01
  • 2021-11-22
相关资源
最近更新 更多