INotifyChanged 接口没有按预期工作 C# Wpf(我第一次实现它)
INotifyChanged Interface is not working as expected C# Wpf (first time I'm implementing it)
我正在开发一个 WPF 应用程序,其中包含一个 DataGrid,其中包含名字、姓氏、电子邮件等个人详细信息。
我正在使用 ObservableCollection
列表作为 DataSource
我的 DataGrid
:
public ObservableCollection<Persons> personsLists = new ObservableCollection<Person>(Controller.SelectAllPersons());
接下来我想实现的是:
例如,当我更改名字或姓氏时,
我正在将它保存到数据库中,我想立即更新 DataGrid。我尝试通过以下 MSDN documentation:
实现 INotifyPropertyChanged
public class Person : MyInherit, INotifyPropertyChanged
{
#region Attributes
private string _fullName;
private int _townId;
private string _firstName;
private Town _town;
private string _lastName;
#endregion
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#region Properties
public Town Town
{
get { return _town; }
set
{
_town = value;
NotifyPropertyChanged("Town");
}
}
public int TownId
{
get { return _townId; }
set
{
_townId = value;
NotifyPropertyChanged("TownId");
}
}
public string FullName
{
get { return _fullName; }
set
{
_fullName = value;
NotifyPropertyChanged("FullName");
}
}
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
NotifyPropertyChanged("FirstName");
}
}
public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
NotifyPropertyChanged("LastName");
}
}
}
这就是我在我的 UI 表单上编辑个人对象的地方:
private void btnPersonEdit_Click(object sender, System.Windows.RoutedEventArgs e)
{
Person selectedPerson = (Person)(dtgPersons.SelectedItem);
if (selectedPerson != null)
{
//GetExistingPerson from DataGrid (gettin obj from list which is source to a DataGrid so it's same as getting it from DataGrid)
var person = personsLists.Where(d => d.Id == selectedPerson.Id).FirstOrDefault();
if (person != null)
{
person.FirstName = txtFirstName.Text;
person.LastName = txtLastName.Text;
person.Town = (Town)cmbTowns.SelectedItem;
person.TownId = selectedPerson.Town.Id;
//Apply changes to a database
Person lastUpdated = Controller.UpdatePerson(person);
dtgPersons.UnselectAll();
}
}
//After this I thought the same item I edited should be updated immediately on a DataGrid but obviously I did something wrong
}
如何在不再次设置源的情况下使用此 INotifyPropertyChanged 接口更新我的 DataGrid,
因为我认为这样做对性能不利:
dtg.ItemsSource=null;
dtg.ItemsSource= personsLists;
XAML:
<DataGrid Grid.Row="1" IsReadOnly="True" Name="dtgPersons" EnableColumnVirtualization = "True"
EnableRowVirtualization ="True" SelectionUnit="FullRow" Background="White" Margin="0,5,0,0"
AutoGenerateColumns="False" RowHeaderWidth="0" MaxWidth="4000" MaxHeight="2000" HorizontalGridLinesBrush="#0091EA"
VerticalGridLinesBrush="#0091EA" CanUserAddRows="False" FontSize="{x:Static local:Globals.dataGridfontSizeContent}"
RowHeight="30" SelectionChanged="dtgPersons_SelectionChanged" >
<DataGrid.CellStyle>
<StaticResource ResourceKey="DataGridCentering"/>
</DataGrid.CellStyle>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#0091EA"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="{x:Static local:Globals.dataGridfontSizeHeader}"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="40"/>
</Style>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightBlue"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FirstName}" CellStyle="{StaticResource DataGridCenteringLeft}"
Header="First Name" Foreground="Black" FontSize="16" FontFamily="Verdana" Width="*" />
<DataGridTextColumn Binding="{Binding LastName}" CellStyle="{StaticResource DataGridCenteringLeft}"
Header="Last Name" Foreground="Black" FontSize="16" FontFamily="Verdana" Width="*" />
</DataGrid.Columns>
</DataGrid>
为什么要在 listaselectedPerson
集合中查找 Person
对象?我猜你想设置所选的属性:
private void btnPersonEdit_Click(object sender, System.Windows.RoutedEventArgs e)
{
Person selectedPerson = (Person)(dtgPersons.SelectedItem);
if (selectedPerson != null)
{
selectedPerson.FirstName = txtIme.Text;
selectedPerson.LastName = txtPrezime.Text;
selectedPerson.Town = (Town)cmbTowns.SelectedItem;
selectedPerson.TownId = selectedPerson.Town.Id;
//Apply changes to a database
Person lastUpdated = Controller.UpdatePerson(selectedPerson);
dtgPersons.UnselectAll();
}
}
我正在开发一个 WPF 应用程序,其中包含一个 DataGrid,其中包含名字、姓氏、电子邮件等个人详细信息。
我正在使用 ObservableCollection
列表作为 DataSource
我的 DataGrid
:
public ObservableCollection<Persons> personsLists = new ObservableCollection<Person>(Controller.SelectAllPersons());
接下来我想实现的是:
例如,当我更改名字或姓氏时, 我正在将它保存到数据库中,我想立即更新 DataGrid。我尝试通过以下 MSDN documentation:
实现 INotifyPropertyChangedpublic class Person : MyInherit, INotifyPropertyChanged
{
#region Attributes
private string _fullName;
private int _townId;
private string _firstName;
private Town _town;
private string _lastName;
#endregion
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#region Properties
public Town Town
{
get { return _town; }
set
{
_town = value;
NotifyPropertyChanged("Town");
}
}
public int TownId
{
get { return _townId; }
set
{
_townId = value;
NotifyPropertyChanged("TownId");
}
}
public string FullName
{
get { return _fullName; }
set
{
_fullName = value;
NotifyPropertyChanged("FullName");
}
}
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
NotifyPropertyChanged("FirstName");
}
}
public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
NotifyPropertyChanged("LastName");
}
}
}
这就是我在我的 UI 表单上编辑个人对象的地方:
private void btnPersonEdit_Click(object sender, System.Windows.RoutedEventArgs e)
{
Person selectedPerson = (Person)(dtgPersons.SelectedItem);
if (selectedPerson != null)
{
//GetExistingPerson from DataGrid (gettin obj from list which is source to a DataGrid so it's same as getting it from DataGrid)
var person = personsLists.Where(d => d.Id == selectedPerson.Id).FirstOrDefault();
if (person != null)
{
person.FirstName = txtFirstName.Text;
person.LastName = txtLastName.Text;
person.Town = (Town)cmbTowns.SelectedItem;
person.TownId = selectedPerson.Town.Id;
//Apply changes to a database
Person lastUpdated = Controller.UpdatePerson(person);
dtgPersons.UnselectAll();
}
}
//After this I thought the same item I edited should be updated immediately on a DataGrid but obviously I did something wrong
}
如何在不再次设置源的情况下使用此 INotifyPropertyChanged 接口更新我的 DataGrid, 因为我认为这样做对性能不利:
dtg.ItemsSource=null;
dtg.ItemsSource= personsLists;
XAML:
<DataGrid Grid.Row="1" IsReadOnly="True" Name="dtgPersons" EnableColumnVirtualization = "True"
EnableRowVirtualization ="True" SelectionUnit="FullRow" Background="White" Margin="0,5,0,0"
AutoGenerateColumns="False" RowHeaderWidth="0" MaxWidth="4000" MaxHeight="2000" HorizontalGridLinesBrush="#0091EA"
VerticalGridLinesBrush="#0091EA" CanUserAddRows="False" FontSize="{x:Static local:Globals.dataGridfontSizeContent}"
RowHeight="30" SelectionChanged="dtgPersons_SelectionChanged" >
<DataGrid.CellStyle>
<StaticResource ResourceKey="DataGridCentering"/>
</DataGrid.CellStyle>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#0091EA"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="{x:Static local:Globals.dataGridfontSizeHeader}"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="40"/>
</Style>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightBlue"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FirstName}" CellStyle="{StaticResource DataGridCenteringLeft}"
Header="First Name" Foreground="Black" FontSize="16" FontFamily="Verdana" Width="*" />
<DataGridTextColumn Binding="{Binding LastName}" CellStyle="{StaticResource DataGridCenteringLeft}"
Header="Last Name" Foreground="Black" FontSize="16" FontFamily="Verdana" Width="*" />
</DataGrid.Columns>
</DataGrid>
为什么要在 listaselectedPerson
集合中查找 Person
对象?我猜你想设置所选的属性:
private void btnPersonEdit_Click(object sender, System.Windows.RoutedEventArgs e)
{
Person selectedPerson = (Person)(dtgPersons.SelectedItem);
if (selectedPerson != null)
{
selectedPerson.FirstName = txtIme.Text;
selectedPerson.LastName = txtPrezime.Text;
selectedPerson.Town = (Town)cmbTowns.SelectedItem;
selectedPerson.TownId = selectedPerson.Town.Id;
//Apply changes to a database
Person lastUpdated = Controller.UpdatePerson(selectedPerson);
dtgPersons.UnselectAll();
}
}