如何在 WPF C# 中使用数据绑定?
How to use data binding in WPF C#?
我想在 WPF 中将我的控件与我的视图模型绑定,并在我的数据库更新时自动更新数据控件。
我实现了一个具有一些 List<myClass>
属性的视图模型,并从数据库接收数据,这些数据将保存在这些属性中。然后我将我的控件源绑定到这些属性。没关系,但是当我从数据库中获取新数据并将其保存在这些属性中时,控件数据不会更新。
我如何以编程方式修复它?
这是我的代码:
public partial class MainWindow : Window
{
ListOfPerson personList1 = new ListOfPerson();
ListOfPerson personList2 = new ListOfPerson();
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
personList1.People.Add(new Person { PersonName = "test1" });
personList2.People.Add(new Person { PersonName = "test2" });
dg.AutoGenerateColumns = false;
PropertyPath prop = new PropertyPath("PersonName");
Binding bind = new Binding();
bind.Mode = BindingMode.TwoWay;
bind.Path = prop;
dg.Columns.Add(new DataGridTextColumn { Header = "Name", Binding = bind });
dg.ItemsSource = personList1.People;
}
public void Refresh()
{
personList1.People = personList2.People;
}
private void btn_Refresh_Click(object sender, RoutedEventArgs e)
{
Refresh();
}
}
public class Person : INotifyPropertyChanged
{
private string name;
public Person()
{
}
public Person(string value)
{
this.name = value;
}
public string PersonName
{
get { return name; }
set
{
name = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
public class ListOfPerson : INotifyPropertyChanged
{
private List<Person> people = new List<Person>();
public List<Person> People
{
get
{
return people;
}
set
{
people = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
您直接分配您的ItemsSource
,即不是绑定。
dg.ItemsSource = personList1.People;
然而,在 Refresh
上,您替换了 personList1
的 People
集合。
personList1.People = personList2.People;
项目源仍然具有对旧集合的引用,因为您直接分配了它。您可以添加一个绑定,它会注意到项目源通过 属性 更改通知实现在 People
属性 中更改了 ListOfPerson
。这应该有效:
Binding itemsSourceBinding = new Binding
{
Source = personList1,
Path = new PropertyPath("People")
};
BindingOperations.SetBinding(dg, DataGrid.ItemsSourceProperty, itemsSourceBinding);
这只是处理这种情况的一种选择。另一种选择是仅使用 单个 ObservableCollection<T>
that you Clear
and fill again or modify in between (if your replace it with a new instance like the list in your code, you run into the same issue as above). It implements the INotifyCollectionChanged
界面并通知更改,例如自动添加、删除或插入项目,这会依次更新 UI。
我想在 WPF 中将我的控件与我的视图模型绑定,并在我的数据库更新时自动更新数据控件。
我实现了一个具有一些 List<myClass>
属性的视图模型,并从数据库接收数据,这些数据将保存在这些属性中。然后我将我的控件源绑定到这些属性。没关系,但是当我从数据库中获取新数据并将其保存在这些属性中时,控件数据不会更新。
我如何以编程方式修复它?
这是我的代码:
public partial class MainWindow : Window
{
ListOfPerson personList1 = new ListOfPerson();
ListOfPerson personList2 = new ListOfPerson();
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
personList1.People.Add(new Person { PersonName = "test1" });
personList2.People.Add(new Person { PersonName = "test2" });
dg.AutoGenerateColumns = false;
PropertyPath prop = new PropertyPath("PersonName");
Binding bind = new Binding();
bind.Mode = BindingMode.TwoWay;
bind.Path = prop;
dg.Columns.Add(new DataGridTextColumn { Header = "Name", Binding = bind });
dg.ItemsSource = personList1.People;
}
public void Refresh()
{
personList1.People = personList2.People;
}
private void btn_Refresh_Click(object sender, RoutedEventArgs e)
{
Refresh();
}
}
public class Person : INotifyPropertyChanged
{
private string name;
public Person()
{
}
public Person(string value)
{
this.name = value;
}
public string PersonName
{
get { return name; }
set
{
name = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
public class ListOfPerson : INotifyPropertyChanged
{
private List<Person> people = new List<Person>();
public List<Person> People
{
get
{
return people;
}
set
{
people = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
您直接分配您的ItemsSource
,即不是绑定。
dg.ItemsSource = personList1.People;
然而,在 Refresh
上,您替换了 personList1
的 People
集合。
personList1.People = personList2.People;
项目源仍然具有对旧集合的引用,因为您直接分配了它。您可以添加一个绑定,它会注意到项目源通过 属性 更改通知实现在 People
属性 中更改了 ListOfPerson
。这应该有效:
Binding itemsSourceBinding = new Binding
{
Source = personList1,
Path = new PropertyPath("People")
};
BindingOperations.SetBinding(dg, DataGrid.ItemsSourceProperty, itemsSourceBinding);
这只是处理这种情况的一种选择。另一种选择是仅使用 单个 ObservableCollection<T>
that you Clear
and fill again or modify in between (if your replace it with a new instance like the list in your code, you run into the same issue as above). It implements the INotifyCollectionChanged
界面并通知更改,例如自动添加、删除或插入项目,这会依次更新 UI。