streamdown
streamdown

Reputation: 390

Updating Model from the ViewModel properties with preservation MVVM pattern

For example I have a Model:

public class PropertiesModel
{
    public bool MaterialEnable { get; set; }
}

ViewModel:

public class ViewModel: INotifyPropertyChanged
{
      private PropertiesModel _model;
      public bool Recalc { get; set; }

      puplic ViewModel (PropertiesModel model)
      {
        _model = model;
        Recalc = _model.MaterialEnabled;
      }
}

And finaly - XAML:

<ToggleSwitch IsChecked="{Binding Recalc}" />

How correctly, according to the pattern, update the property in the Model from the ViewModel?

Upvotes: 0

Views: 66

Answers (1)

lokusking
lokusking

Reputation: 7456

This is not meant to be an true answer. This one should just show the relations, on how everything depends:

First, your Window

<Window x:Class="MySample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MySample"
        xmlns:po="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
        mc:Ignorable="d"        
        Title="MainWindow" >
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVis"/>     
    </Window.Resources>

    <Grid Height="200">
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel>
            <CheckBox Content="ShowListBox" x:Name="chk"></CheckBox>
            <ListView ItemsSource="{Binding Ponys}" x:Name="lst" SelectedItem="{Binding SelectedPony}">
                <ListView.Visibility>
                    <Binding ElementName="chk" Path="IsChecked" Converter="{StaticResource BoolToVis}"/>
                </ListView.Visibility>
                <ListView.ItemTemplate>
                    <DataTemplate DataType="{x:Type local:Pony}">
                        <WrapPanel Background="{Binding Color}" >
                            <TextBlock Text="{Binding Id}" Margin="0,0,5,0" Padding="2"/>
                            <TextBox Text="{Binding Name}"></TextBox>
                        </WrapPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <WrapPanel>
                <TextBlock Text="New Description for selected Pony: "/>
                <TextBox Width="100" Text="{Binding SelectedPony.Name, UpdateSourceTrigger=PropertyChanged}"></TextBox>
            </WrapPanel>
        </StackPanel>
    </Grid>
</Window>

Second, a Model

public class Pony : INotifyPropertyChanged
    {
        public int Id {
            get; set;
        }
        private string _name;
        public string Name {
            get { return this._name; }
            set { this._name = value;
                this.OnPropertyChanged("Name");
            }
        }

        public Brush Color { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

Third, the Usage

public partial class MainWindow : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public MainWindow()
        {
            InitializeComponent();
            this.Ponys = new List<Pony>();
            this.Ponys.Add(new Pony() { Id = 1, Name = "Fluffy", Color = Brushes.DeepPink });
            this.Ponys.Add(new Pony() { Id = 2, Name = "Not so fluffy", Color = Brushes.Chocolate });

            this.DataContext = this;
        }

        private Pony _pony;
        public Pony SelectedPony {
            get { return this._pony; }
            set {
                this._pony = value;
                this.OnPropertyChanged("SelectedPony");
            }
        }

        public List<Pony> Ponys { get; set; }
    }

Some Notes:

  1. I made no MainViewModel because of lazyness, so i just used CodeBehind
  2. As you see, there are bound DataTemplates, pure GUI-bindings, Model-Manipulations and the usage of the DataContext. Enough for a jumpstart
  3. I highly recommend you, not to use any 3rd-Party-Stuff if you want to learn and understand how everything works. I know this so comfortable, not to type everything over and over again. But thats the way, you truely understand whats happening. Also you can set Breakpoints and take a deep look on whats going on
  4. I didnt implement everywhere the PropertyChanged, also because of lazyness
  5. If you dont use this Fody-thingy, there is no need for Constructor-Injections

Upvotes: 1

Related Questions