WPF Master \ Detail: How do I keep the Master to update when editing Detail?

I have a fairly straight forward MVVM Master \ Detail window -

XAML snippet:                                                           

        <Grid Grid.Row="0" Grid.Column="0" >
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Label Content="ID:" Grid.Row="0" Grid.Column="0"/>
            <Label Content="{Binding SelectedCustomer.CustId}" Grid.Row="0" Grid.Column="1"/>

            <Label Content="Name:" Grid.Row="1" Grid.Column="0"/>
            <TextBox Text="{Binding SelectedCustomer.Name}"  Grid.Row="1" Grid.Column="1"/>

            <Label Content="Address:" Grid.Row="2" Grid.Column="0"/>
            <TextBox Text="{Binding SelectedCustomer.Address}"  Grid.Row="2" Grid.Column="1"/>
            <Label Content="City:" Grid.Row="3" Grid.Column="0"/>
            <TextBox Text="{Binding SelectedCustomer.City}"  Grid.Row="3" Grid.Column="1"/>
            <Label Content="State:" Grid.Row="4" Grid.Column="0"/>
            <TextBox Text="{Binding SelectedCustomer.State}"  Grid.Row="4" Grid.Column="1"/>
            <Label Content="ZIP:" Grid.Row="5" Grid.Column="0"/>
            <TextBox Text="{Binding SelectedCustomer.ZIP}"  Grid.Row="5" Grid.Column="1"/>

        </Grid>

        <Grid Grid.Row="1" Grid.Column="0">
            <DataGrid ItemsSource="{Binding CustomerCollection}" SelectedItem="{Binding SelectedCustomer}"></DataGrid>
        </Grid>
    </Grid>

      

Nothing really like about the model:

    public ObservableCollection<Customer> CustomerCollection { get; set; }

    private Customer _selectedCustomer;
    public Customer SelectedCustomer
    {
        get
        {
            return _selectedCustomer;
        }
        set
        {
            _selectedCustomer = value;
            OnPropertyChanged("SelectedCustomer");
        }
    }

      

I can select the Master line and the details will be filled in accordingly. This part works great.

My problem occurs when I edit Part, it changes master before the user clicks Save. If I change one of the properties and lose focus, the data binding sets the "Master" line to be the same as the new information. I've tried different versions of = OneWay mode and they don't help.

How do I create a data binding for a SelectedItem only to the datagrid output and not back? I update the datagrid when the user clicks the save button, this is not a problem. More important to me is that the recording does not change the average stream, rather than updating the grid too often.

0


source to share


2 answers


You have to set the OneTime binding to the properties of the collection, not the collection itself. Try to disable autogeneratecolumns on your grid and define the columns yourself with onetime binding. This should get the behavior you want.

Something like this (not tested):



<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Customers}" SelectedItem="
     {Binding SelectedCustomer}">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Name, Mode=OneTime}" />
        <DataGridTextColumn Binding="{Binding Address, Mode=OneTime}" />
    </DataGrid.Columns>
</DataGrid>

      

If you really want to separate the part from the master, I recommend having a separate selectedCustomer property and copying it to the grid-bound collection when you're done editing. Onetime binding is nice, but you have to update your grid manually, which requires a bit of code if you want to work with strict MVVM. Also note that when you edit the details, the SelectedCustomer will still update in your collection in the ViewModel, the grid will not show the changes yet. Therefore, if you click the "Save" button, the latest information will be written to the database.

+1


source


You can use UpdateSourceTrigger But in this case you need to execute all controls in detail and update the source manually.



More complex solution - you can load the selected row into the detailed form not from the grid, but from the server again.

0


source







All Articles