0

我对这个 MVVM 想法很陌生,正在尝试编写我的第一个 MVVM 应用程序来弄湿我的脚。取得了一点进步,但随着我的进步遇到了障碍。我的问题是一个非常基本的基本问题,可以通过后面的代码轻松解决,但不鼓励这样做,因为它违反了我猜的松散耦合原则。所以这是我遇到的问题:

我的模型:

public class ToDoItemModel
{
    private DateTime    _TodoDate;
    private string      _TodoDescription;
    private TimeSpan    _TodoTimeSpan;
    private string      _StartTime;

    public string StartTime
    {
        get { return _StartTime; }
        set
        {
            _StartTime = value;
        }
    }
    public TimeSpan ToDoTimeSpan
    {
        get { return _TodoTimeSpan; }
        set
        {
            _TodoTimeSpan = value;
        }
    }        
    public string ToDoDescription
    {
        get { return _TodoDescription; }
        set
        {
            _TodoDescription = value;
        }
    }      
    public DateTime ToDoDate
    {
        get { return _TodoDate; }
        set
        {
            _TodoDate = value;
        }
    }

    public override string ToString()
    {
        return string.Format("Date: {0}- Time: {1}- Duration: {2}- Description: {3}",_TodoDate.ToString("d"),_StartTime,_TodoTimeSpan,_TodoDescription);
    }
}

我的视图模型:

    public class ToDoListModelView:INotifyPropertyChanged
    {
        List<ToDoItemModel> _myModel = new List<ToDoItemModel>();
        public ICommand AddToDo
        {
            get
            {
                return new RelayCommand(addToDo);
            }
        }
        public ToDoListModelView()
        {
            _myModel.Add(new ToDoItemModel() { ToDoDate = DateTime.Now, ToDoDescription = "Testing 1" });
            _myModel.Add(new ToDoItemModel() { ToDoDate = DateTime.Now.AddDays(1), ToDoDescription = "Testing 2" });
        }
        public List<ToDoItemModel> myModel 
        { 
            get { return _myModel; } 
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            var handler = this.PropertyChanged;
            if (handler!=null)
            {
                handler(this, e);
            }
        }
        public void RaisePropertyChanged(string PropertyName)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(PropertyName));
        }

        private void addToDo()
        {
            _myModel.Add(new ToDoItemModel() { ToDoDate = DateTime.Now.AddDays(2), ToDoDescription = "From Relay Command" });
RaisePropertyChanged("DataGridChanged");
        }
    }

viewModel 实现了 INotifyPropertyChanged,并使用了实现 ICommand 接口的类 RelayCommand。

我的看法是:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestWPF" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="TestWPF.MainWindow"
        Title="MainWindow" Height="350" Width="525">
    <Grid Margin="1,0,-1,0" d:DataContext="{d:DesignData /SampleData/ToDoListModelSampleData.xaml}">
        <Button x:Name="AddToDoButton" Content="Add Todo Item&#xA;" 
                  HorizontalAlignment="Left" Margin="419,90,0,0" VerticalAlignment="Top" Width="78" Height="33.04"
                  Command="{Binding AddToDo}"/>
        <DataGrid x:Name="TodoList" HorizontalAlignment="Left" 
                  Margin="33,184,0,0" VerticalAlignment="Top" 
                  RenderTransformOrigin="-0.833,-0.846" Height="108" Width="464" 
                  ItemsSource="{Binding myModel}" 
                  Style="{DynamicResource ToDoEntry}"/>
    </Grid>
</Window>

当我按 F5 时,应用程序运行并显示了 2 个初始记录。 在此处输入图像描述

但是,当我点击添加按钮时,我看到新记录是在内部添加的,但数据网格没有更新。我知道数据网格需要以某种方式刷新,但我不确定如何告诉网格刷新 MVVM 应该处理的方式。我当前的代码就这么简单:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ToDoListModelView();
    }
}

根据我从 Microsoft 网站阅读的文档,如果我理解正确, RaisePropertyChange 应该标记发生更改事件,我只是很困惑如何使用 xaml 绑定事件以刷新网格,而无需任何代码。请帮忙。

4

3 回答 3

4

将您的更改List<ToDoItemModel>ObservableCollection<ToDoItemModel>

当从集合中添加或删除项目时, AList<T>不会通知 UI 进行更新,而 anObservableCollection<T>会。

于 2014-05-23T20:14:44.113 回答
2

您需要使用绑定 模式 TwoWay还将您的列表更改为 ObservableCollection

ObservableCollection 将在添加或删除记录时通知 UI。

ObservableCollection<ToDoItemModel> _myModel = new ObservableCollection<ToDoItemModel>();
public ICommand AddToDo
{
get
  {
  return new RelayCommand(addToDo);
  }
}
public ToDoListModelView()
{
 _myModel.Add(new ToDoItemModel() { ToDoDate = DateTime.Now, ToDoDescription = "Testing 1" });
 _myModel.Add(new ToDoItemModel() { ToDoDate = DateTime.Now.AddDays(1), ToDoDescription = "Testing 2" });
}
public ObservableCollection <ToDoItemModel> myModel 
{ 
 get { return _myModel; } 
}

XAML:

  <DataGrid x:Name="TodoList" HorizontalAlignment="Left" 
                      Margin="33,184,0,0" VerticalAlignment="Top" 
                      RenderTransformOrigin="-0.833,-0.846" Height="108" Width="464" 
                      ItemsSource="{Binding myModel,Mode=TwoWay}" 
                      Style="{DynamicResource ToDoEntry}"/>
于 2014-05-23T20:12:25.533 回答
0

使用 ObservableCollection 而不是 Lists(如上所述),并 UpdateSourceTrigger=PropertyChanged在 XAML 中设置。

代码

<DataGrid x:Name="TodoList" HorizontalAlignment="Left" Margin="33,184,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.833,-0.846" Height="108" Width="464" ItemsSource="{Binding Path=myModel,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged }" Style="{DynamicResource ToDoEntry}"/>

于 2014-05-23T21:25:43.840 回答