簡體   English   中英

WPF DataGrid:使用MVVM立即保存單元格更改

[英]WPF DataGrid: Save cell changes immediately with MVVM

我有一個簡化的DataGrid看起來像這樣:

<DataGrid AutoGenerateColumns="False" 
          ItemsSource="{Binding Parts}" 
          SelectedItem="{Binding SelectedPart}" >
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Path=Name, Mode=TwoWay}" />
        <DataGridTemplateColumn Header="PartType" >
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.PartTypes}" 
                              SelectedItem="{Binding PartType, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding PartType}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

我的ViewModel看起來像這樣:

public class PartListViewModel
{
    private ObservableCollection<Part> _parts;
    public ObservableCollection<Part> Parts
    {
        get { return _parts; }
        set
        {
            _parts = value;
             OnPropertyChanged("Parts");
        }
    }

    private Part _selectedPart;
    public Part SelectedPart
    {
        get { return _selectedPart; }
        set
        {
            _selectedPart = value;
            OnPropertyChanged("SelectedPart");
        }
    }
}

現在我希望將datagrid單元格的更改立即存儲到數據庫中。 如何在MVVM中做到這一點?

目前我收聽DataGrid的OnCellEditEnding事件並將記錄保存在代碼隱藏中。 但這很難看:

private void DataGrid_OnCellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    var viewModel = (PartListViewModel) DataContext;
    viewModel.SavePart((Part) e.Row.Item);
}

你可以做這樣的事情。 (你需要添加對System.Windows.Interactivity引用, 你可以從這里下載程序集

然后在XAML中添加對命名空間的引用。 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

<i:Interaction.Triggers>
  <i:EventTrigger EventName="CellEditEnding">
     <i:InvokeCommandAction Command="{Binding SomeCommand}"/>
  </i:EventTrigger>
</i:Interaction.Triggers>

一種方法是使用事件代理,例如Prism庫附帶的EventAggregator

將每個Part實體(“model”)添加到Parts集合中時,您可以使用自己的viewmodel(PartViewModel)將其包裝,然后可以在其組成部分中偵聽屬性更新,然后通過事件代理發布更新消息。 然后,您可以擁有一個偵聽(訂閱)該消息並保存已發布的有效內容的服務(有效負載可以是已修改的部分)。

您可以處理視圖模型中所有Part對象的PropertyChanged事件:

public class PartListViewModel
{
    private ObservableCollection<Part> _parts;
    public ObservableCollection<Part> Parts
    {
        get { return _parts; }
        set
        {
            if(_parts != null) _parts.CollectionChanged -= OnCollectionChanged;
            _parts = value;
            if (_parts != null) _parts.CollectionChanged += OnCollectionChanged;
            //OnPropertyChanged("Parts");
        }
    }

    private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach (object part in e.NewItems)
            {
                (part as INotifyPropertyChanged).PropertyChanged
                    += new PropertyChangedEventHandler(PartPropertyChanged);
            }
        }

        if (e.OldItems != null)
        {
            foreach (object part in e.OldItems)
            {
                (part as INotifyPropertyChanged).PropertyChanged
                    -= new PropertyChangedEventHandler(PartPropertyChanged);
            }
        }
    }

    private void PartPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if(e.PropertyName == "PartType")
        {
            //save to database...
        }
    }
}

這當然是Part類實現INotifyPropertyChanged

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM