简体   繁体   中英

How to use data binding in WPF C#?

I want to bind my controls with my view model in WPFand automatically update data controls when my database is updated. I implemented a view model that has some List<myClass> properties and receives data from a data base that will be saved in these properties. Then I bind my controls source to these properties. It's ok, but when I get new data from data base and save it in in these properties, the controls data does not update. How can I fix it programmatically?

This is my code:

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

You assign your ItemsSource directly, that is not a binding .

dg.ItemsSource = personList1.People;

On Refresh however, you replace the People collection of personList1 .

personList1.People = personList2.People;

The items source still has the reference to the old collection, since you assigned it directly. You could instead add a binding, which would notice that the items source changed through the property changed notification implementation in ListOfPerson for the People property. This should work:

Binding itemsSourceBinding = new Binding
{
    Source = personList1,
    Path = new PropertyPath("People")
};
BindingOperations.SetBinding(dg, DataGrid.ItemsSourceProperty, itemsSourceBinding);

This is only one option to handle this scenario. Another option is to use just a single 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 interface and notifies changes, like adding, removing or inserting items automatically, which updates the UI in turn.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM