yellavon
yellavon

Reputation: 2881

Update bindings on button click

I have some XAML that binds to my properties in the view model but I don't want them updated until the user clicks the save button. After some reading on MSDN it looks I could use BindingGroup.UpdateSources(). However I don't know how to get the container element for my XAML so that I can update the bound properties at the same time. What do I need for my code behind?

Here is my XAML:

<DockPanel  VerticalAlignment="Stretch" Height="Auto">
    <Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="2">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />            
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />      
            </Grid.ColumnDefinitions>

            <Grid.BindingGroup>
                <BindingGroup Name="myBindingGroup1">
                </BindingGroup>
            </Grid.BindingGroup>                

            <TextBlock Grid.Column="0" Grid.Row="0" Text="Address:" />
            <TextBox Grid.Column="1" Grid.Row="0" Text="{Binding myObject.Address, BindingGroupName=myBindingGroup1, UpdateSourceTrigger=Explicit}" />

            <TextBlock Grid.Column="0" Grid.Row="1" Text="ID:" />
            <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding myObject.ID, BindingGroupName=myBindingGroup1, UpdateSourceTrigger=Explicit}" />               
        </Grid>
    </Border>
    <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" Height="35" HorizontalAlignment="Center" VerticalAlignment="Bottom">
        <Button Content="Save" Command="saveItem" />
    </StackPanel>
</DockPanel>

Upvotes: 0

Views: 107

Answers (1)

Ondrej Janacek
Ondrej Janacek

Reputation: 12616

I don't know about binding groups, but I know how to do it another way.

Have an object you are binding to in your view-model as you have it now and let it be updated whenever something changes in the view. Before any changes to it (when you create it for instance) create a deep copy of the object (copy actual values, not just references for reference types) in your view-model.

When a user pushes the Save button, simply propagate changes from the bounded properties to the copy and do whatever you need to do with it (store in db, ...). If you are not happy with new values, simply overwrite them from the copy.

If the bounded object is an object from some model, do not directly propagate changes to the model, use some temporary fields.

Something like the following example.

public class MainViewModel : ViewModelBase
{
    private PersonModel model;
    private Person person;

    public Person Person
    {
        get { return person; }
        set { SetField(ref person, value); } // updates the field and raises OnPropertyChanged
    }

    public ICommand Update { get { return new RelayCommand(UpdatePerson); } }

    private void UpdatePerson()
    {
        if (someCondition)
        {
            // restore the old values
            Person = new Person(model.Person.FirstName, model.Person.LastName, model.Person.Age);
        }

        // update the model
        model.Person = new Person(Person.FirstName, Person.LastName, Person.Age);
    }
}

Upvotes: 1

Related Questions