使用保留MVVM模式从ViewModel属性更新Model

本文关键字:ViewModel 属性 更新 Model 模式 保留 MVVM | 更新日期: 2023-09-27 17:57:26

例如,我有一个型号:

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

最后-XAML:

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

根据模式,如何正确地从ViewModel更新Model中的属性?

  • 更新整个模型
  • 是否更新添加事件的特定属性
  • 依赖注入

使用保留MVVM模式从ViewModel属性更新Model

这不是一个真实的答案。这个应该只是显示关系,取决于一切如何依赖:

首先,您的窗口

<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>

其次,模型

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

第三,使用

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

一些注释

  1. 由于懒散,我没有制作MainViewModel,所以我只使用CodeBehind
  2. 如您所见,有绑定的DataTemplates、纯GUI绑定、模型操作和DataContext的使用。足够启动了
  3. 我强烈建议你,如果你想学习和了解一切是如何工作的,不要使用任何第三方的东西。我知道这很舒服,不用一遍又一遍地打字。但这是一种方式,你真正了解正在发生的事情。此外,您还可以设置断点并深入了解发生了什么
  4. 我没有到处实现PropertyChanged,也是因为懒惰
  5. 如果你不使用这个Fody的东西,就不需要构造函数注入
相关文章: