[英]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.