簡體   English   中英

WPF 將列表數據綁定到 DataGrid - 不更新數據網格

[英]WPF DataBinding of list to DataGrid - no update of datagrid

我剛剛開始使用 WPF 進行編程,並且遇到了 WPF 中的數據網格不會更新值的問題。 我已經嘗試了幾天不同的事情,但不幸的是最后沒有任何效果。 當 GUI 被啟動時,綁定本身會起作用。 我添加了一個按鈕來將新數據添加到數據網格。 數據將在列表中更新,但不會在數據網格中更新。 如果有人可以幫助我,那就太好了。

MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        List<Person> list = new List<Person>();
        ObservableCollection<Person> obsCol = new ObservableCollection<Person>();

        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = this;           

            Person pers = new Person();
            pers.Name = "Tom";
            pers.Gender = "m";
            list.Add(pers);

            pers = new Person();
            pers.Name = "Bianca";
            pers.Gender = "w";
            list.Add(pers);

            obsCol = new ObservableCollection<Person>(list);

            grid.ItemsSource = obsCol;
        }

        private void Bt1_Click(object sender, RoutedEventArgs e)
        {
            Person pers = new Person();
            pers.Name = "Andreas";
            pers.Gender = "m";
            list.Add(pers);
            obsCol = new ObservableCollection<Person>(list);

            int u = 0;
        }
    }
}

個人.cs:

public class Person:INotifyPropertyChanged
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; onPropertyChanged(this, "Name"); }
    }

    private string gender;

    public string Gender
    {
        get { return gender; }
        set { gender = value; onPropertyChanged(this, "Gender"); }
    }

    // Declare the PropertyChanged event
    public event PropertyChangedEventHandler PropertyChanged;

    // OnPropertyChanged will raise the PropertyChanged event passing the
    // source property that is being updated.
    private void onPropertyChanged(object sender, string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
        }
    }


}

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    List<Person> list = new List<Person>();
    ObservableCollection<Person> obsCol = new ObservableCollection<Person>();

    public MainWindow()
    {
        InitializeComponent();

        this.DataContext = this;           

        Person pers = new Person();
        pers.Name = "Tom";
        pers.Gender = "m";
        list.Add(pers);

        pers = new Person();
        pers.Name = "Bianca";
        pers.Gender = "w";
        list.Add(pers);

        obsCol = new ObservableCollection<Person>(list);

        grid.ItemsSource = obsCol;
    }

    private void Bt1_Click(object sender, RoutedEventArgs e)
    {
        Person pers = new Person();
        pers.Name = "Andreas";
        pers.Gender = "m";
        list.Add(pers);
        obsCol = new ObservableCollection<Person>(list);
    }
}

在 Bt1_點擊添加

grid.ItemsSource = obsCol;

在最后

不要創建新集合。 相反,將新的 Person object 添加到現有的:

private void Bt1_Click(object sender, RoutedEventArgs e)
{
    var pers = new Person
    {
        Name = "Andreas",
        Gender = "m"
    };

    obsCol.Add(pers);
}

如果需要,在添加新數據之前清除集合,通過

obsCol.Clear();

編輯:當然你根本不需要list成員:

private readonly ObservableCollection<Person> obsCol
    = new ObservableCollection<Person>();

public MainWindow()
{
    InitializeComponent();

    DataContext = this; // this seems also pointless       

    grid.ItemsSource = obsCol;

    var pers = new Person
    {
        Name = "Tom",
        Gender = "m"
    };
    obsCol.Add(pers);

    pers = new Person
    {
        Name = "Bianca",
        Gender = "w"
    };
    obsCol.Add(pers);
}

僅當您對屬性具有綁定時, DataContext 分配才有用,例如

public ObservableCollection<Person> ObsCol { get; }
    = new ObservableCollection<Person>();

使用此 XAML:

<DataGrid ItemsSource="{Binding ObsCol}" .../>

我強烈建議您將 ViewModel 與 Code-Behind (MainWindow.xaml.cs) 分開,並且只在那里初始化 ViewModel。

我會在 Xaml 中進行綁定。 所以,我的 MainWindow.xaml 看起來像這樣:

<Window x:Class="WpfAppAddPerson.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>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <StackPanel Grid.Row="0">
        <Button Content="add andreas" x:Name="ButtonAddAndreas" Click="ButtonAddAndreas_OnClick" Margin="5" Padding="5"/>
    </StackPanel>

    <DataGrid Grid.Row="1" ItemsSource="{Binding Persons}" CanUserAddRows="False" CanUserDeleteRows="False" IsReadOnly="True" Margin="10">

    </DataGrid>
</Grid>
</Window>

后面的代碼(MainWindow.xaml.cs):

using System.Windows;
namespace WpfAppAddPerson
{
    public partial class MainWindow : Window
    {
        private MainWindowViewModel _vm;

        public MainWindow()
        {
            InitializeComponent();

            _vm = new MainWindowViewModel();
            DataContext = _vm;
        }

        private void ButtonAddAndreas_OnClick(object sender, RoutedEventArgs e)
        {
            var p = new Person
            {
                Name = "Andreas",
                Gender = "m"
            };

            _vm.Persons.Add(p);

        }
    }
}

視圖模型(MainWindowViewModel.cs):

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using WpfAppAddPerson.Annotations;

namespace WpfAppAddPerson
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public MainWindowViewModel()
        {
            Persons = new ObservableCollection<Person>();

            var p1 = new Person
            {
                Name = "Tom",
                Gender = "m"
            };

            Persons.Add(p1);

            var p2 = new Person
            {
                Name = "Bianca",
                Gender = "w"
            };

            Persons.Add(p2);
        }

        public ObservableCollection<Person> Persons { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

還有人 class:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using WpfAppAddPerson.Annotations;

namespace WpfAppAddPerson
{
    public class Person : INotifyPropertyChanged
    {
        private string _name;
        private string _gender;

        public string Name
        {
            get => _name;
            set
            {
                _name = value;
                OnPropertyChanged();
            }
        }

        public string Gender
        {
            get => _gender;
            set { _gender = value; OnPropertyChanged(); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM