使用保留MVVM模式

时间:2016-07-18 16:54:28

标签: c# wpf mvvm

例如,我有一个模型:

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

视图模型:

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更新模型中的属性?

  • 更新整个模型?
  • 更新添加事件的具体属性?
  • 依赖注入?

1 个答案:

答案 0 :(得分:1)

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

首先,您的窗口

<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-thingy,则不需要构造函数注射