使用保留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中的属性?
- 更新整个模型
- 是否更新添加事件的特定属性
- 依赖注入
这不是一个真实的答案。这个应该只是显示关系,取决于一切如何依赖:
首先,您的窗口
<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; }
}
一些注释:
- 由于懒散,我没有制作
MainViewModel
,所以我只使用CodeBehind - 如您所见,有绑定的
DataTemplates
、纯GUI绑定、模型操作和DataContext
的使用。足够启动了 - 我强烈建议你,如果你想学习和了解一切是如何工作的,不要使用任何第三方的东西。我知道这很舒服,不用一遍又一遍地打字。但这是一种方式,你真正了解正在发生的事情。此外,您还可以设置断点并深入了解发生了什么
- 我没有到处实现
PropertyChanged
,也是因为懒惰 - 如果你不使用这个Fody的东西,就不需要构造函数注入