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

私がマイクロソフトのサイトから読んだドキュメントによると、それを正しく理解している場合、RaisePropertyChange は変更イベントが発生したことを示すことになっています。助けてください。

4

3 に答える 3

4

に変更List<ToDoItemModel>しますObservableCollection<ToDoItemModel>

はアイテムがコレクションに追加またはコレクションから削除されたList<T>ときに更新するように UI に通知しませんが、 は通知ObservableCollection<T>します。

于 2014-05-23T20:14:44.113 に答える
2

Binding Mode を使用する必要があり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 を使用し (上で説明したように)、 UpdateSourceTrigger=PropertyChangedXAML で設定します。

コード:

<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 に答える