列表到DataGrid的WPF DataBinding-没有更新数据网格



我刚开始用WPF编程,遇到了WPF中的数据网格不会更新值的问题。我已经尝试了几天不同的东西,但不幸的是,最后什么都没用。当GUI被启动时,绑定本身确实起作用。我添加了一个按钮,将新数据添加到数据网格中。数据将在列表中更新,但不会在数据网格中更新。如果有人能帮我就太好了。

主窗口.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;
}
}
}

人物:

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));
}
}

}

主窗口.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;

最后

我强烈建议您将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);
}
}
}

ViewModel(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));
}
}
}

以及人员类别:

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));
}
}
}

不要创建新集合。相反,将新的Person对象添加到现有对象中:

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

如果需要,在添加新数据之前,通过清除集合

obsCol.Clear();

EDIT:当然你根本不需要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}" .../>

最新更新