Update DataGrid in WPF from another window

2019-06-23 20:05发布

问题:

I have a DataGrid control on a window called MainWindow. From MainWindow i open another window called NewCustomerWindow using the following code on a button click.

NewCustomerWindow newCustomerWindow = new NewCustomerWindow();
newCustomerWindow.ShowDialog();

In the NewCustomerWindow i have a form with textboxes where someone can enter information about a customer and then these information are saved into a database. After i save these information i want to update the DataGrid in the MainWindow so i use the following code

var mainWindow = Application.Current.Windows
                .OfType<MainWindow>()
                .FirstOrDefault(window => window is MainWindow);

mainWindow.customersGrid.Items.Add(new 
            {
                CustomerID = txtCustomerID.Text,
                CompanyName = txtCompanyName.Text,
                ContactName = txtContactName.Text,
                ContactTitle = txtContactTitle.Text,
                Address = txtAddress.Text,
                City = txtCity.Text,
                Region = txtRegion.Text,
                PostalCode = txtPostalCode.Text,
                Country = txtCountry.Text,
                Phone = txtPhone.Text,
                Fax = txtFax.Text
            });

The above code returns the following error: "Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead."

customersGrid is the name of the DataGrid in MainWindow and its structure is as follows.

<DataGrid AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="8,29,8,8" Name="customersGrid" VerticalAlignment="Stretch" Loaded="customersGrid_Loaded">
        <DataGrid.Columns>
            <DataGridTextColumn Width="Auto" Binding="{Binding CustomerID}" Header="Κωδικός Πελάτη"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding CompanyName}" Header="Όνομα Εταιρίας"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding ContactName}" Header="Όνομα Επαφής"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding ContactTitle}" Header="Τίτλος Επαφής"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding Address}" Header="Διεύθυνση"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding City}" Header="Πόλη"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding Region}" Header="Περιοχή"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding PostalCode}" Header="Ταχυδρομικός Κώδικας"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding Country}" Header="Χώρα"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding Phone}" Header="Τηλέφωνο"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding Fax}" Header="Fax"/>
        </DataGrid.Columns>
    </DataGrid>

I suppose that a solution is to set the ItemsSource property of the DataGrid again with all the data but this is not a good choice because the customers data is coming from a wcf service which brings a lot of records. So, what is a good solution to this problem? Thank you in advance.

回答1:

you set your MainWindow.DataContext = MainViewModel.Instance (your choice to create it a singleton or not)

your MainViewModel class should have an observableCollection dependency property lets call it Customers. you bind your DataGrid to to Customers

<DataGrid ItemsSource="{Binding Customers}" />

so when you want to update the datagrid you just update Customers (for example from NewCustomerWindow) and the dataGrid will automatically be updated

here are nice examples:

A-Practical-Quick-start-Tutorial-on-MVVM-in-WPF

DataGrid Tutorial