在嵌套的ObservableCollection中提升PropertyChanged(值矩阵)

时间:2014-11-26 12:07:33

标签: c# wpf datagrid catel

我有一个绑定到DataGrid的对象矩阵:

在ViewMOdel中,矩阵本身被打包成一个ObservableCollection:

public ObservableCollection<ObservableCollection<object>> MyMatrix {get; set;}

我的问题是当我更改Datagrid中的值时,这些值不会立即在绑定的集合中更新。

如何在输入一个单元格后立即使datagrid更新其数据源?

以下是我的代码:

XAML:

<Window x:Class="TestMatrix.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:Behaviours="clr-namespace:TestMatrix.ViewModels.Helpers.Behaviours"
        xmlns:ViewModels="clr-namespace:TestMatrix.ViewModels">

    <Window.DataContext>
        <ViewModels:MainWindowViewModel/>
    </Window.DataContext>

    <StackPanel Orientation="Vertical">
        <ToolBar VerticalAlignment="Top"            Height="Auto">
            <Button Grid.Row="1" Height="50" Width="200"  Content="Show" Command="{Binding ShowCmd}"/>
        </ToolBar>
        <ToolBar VerticalAlignment="Top"            Height="Auto">
            <TextBox Width="200" Text="{Binding Data.AString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </ToolBar>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <DataGrid AutoGenerateColumns="False"                               
                                        Width="Auto"
                                        Height="Auto"
                                        Margin="3"
                                        FontSize="15"
                                        FontWeight="Bold"
                                        CanUserAddRows="False" 
                                        CanUserDeleteRows="False"
                                        CanUserReorderColumns="False" 
                                        CanUserSortColumns="False"
                                        ItemsSource="{Binding Data.MarketerMixMatrix, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Behaviours:DataGridColumnsBehavior.BindableColumns="{Binding OnlineMarketerMixColumns, Mode=TwoWay}">

            </DataGrid>
        </Grid>
    </StackPanel>         </Window>

视图模型:

using Catel.MVVM;
using System;
using Catel.Data;
using TestMatrix.Models;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows.Data;
using System.Collections.Generic;


namespace TestMatrix.ViewModels
{
    /// <summary>
    /// name view model.
    /// </summary>
    public class MainWindowViewModel : ViewModelBase
    {
        #region Properties
        /// <summary>
        /// Gets or sets the property value.
        /// </summary>
        public ObservableCollection<DataGridColumn> OnlineMarketerMixColumns
        {
            get { return GetValue<ObservableCollection<DataGridColumn>>(OnlineMarketerMixColumnsProperty); }
            set { SetValue(OnlineMarketerMixColumnsProperty, value); }
        }

        /// <summary>
        /// Register the OnlineMarketerMixColumns property so it is known in the class.
        /// </summary>
        public static readonly PropertyData OnlineMarketerMixColumnsProperty = RegisterProperty("OnlineMarketerMixColumns", typeof(ObservableCollection<DataGridColumn>), null);

        /// <summary>
        /// Gets or sets the property value.
        /// </summary>
        public ExtractedOnlineData Data
        {
            get { return GetValue<ExtractedOnlineData>(DataProperty); }
            set { SetValue(DataProperty, value); }
        }

        /// <summary>
        /// Register the Data property so it is known in the class.
        /// </summary>
        public static readonly PropertyData DataProperty = RegisterProperty("Data", typeof(ExtractedOnlineData), null);

        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="MainWindowViewModel"/> class.
        /// </summary>
        public MainWindowViewModel()
        {

            Data = new ExtractedOnlineData();

            ObservableCollection<ObservableCollection<object>> aMatrix = new ObservableCollection<ObservableCollection<object>>();
            ObservableCollection<object> innerMatrix = new ObservableCollection<object>() { 1, 2, 3, 4 };
            aMatrix.Add(innerMatrix);
            Data.MarketerMixMatrix = aMatrix;

            OnlineMarketerMixColumns = new ObservableCollection<DataGridColumn>();

            for (int i = 0; i < 4; i++)
            {
                var column = new DataGridTextColumn();

                OnlineMarketerMixColumns.Add(
                    new DataGridTextColumn
                    {
                        Header = string.Format("ColumnNumber"+i),
                        Binding = new Binding(string.Format("[{0}]", i))
                    });
            }
        }}

型号:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace TestMatrix.Models
{
    public class ExtractedOnlineData : INotifyPropertyChanged
    {
        public ExtractedOnlineData()
        {
            this.ColumnNames = new List<string>();
            this.MarketerMixMatrix = new ObservableCollection<ObservableCollection<object>>();

        }

        private ObservableCollection<ObservableCollection<object>> marketerMixMatrix;

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// Spaltenname der eingelesene Datei.
        /// </summary>
        public List<string> ColumnNames { get; set; }


        /// <summary>
        /// Vermarkter-Matrix.
        /// </summary>
        public ObservableCollection<ObservableCollection<object>> MarketerMixMatrix
        {
            get { return marketerMixMatrix; }
            set { 
                marketerMixMatrix = value;
                RaisePropertyChanged("MarketerMixMatrix");
                }
        }

        /// <summary>
        /// 
        /// </summary>
        public string AString { get; set; }
    }
}

1 个答案:

答案 0 :(得分:1)

我发现您尝试使用UpdateSourceTrigger=PropertyChanged ItemsSource上的DataGrid来解决您的问题。您想要的是要更新单元格更改的单元格绑定源,而不是DataGrid项目。

有了这个推理,很明显在实例化DataGridTextColumn属性的OnlineMarketerMixColumns对象时需要调整绑定:

for (int i = 0; i < 4; i++)
{
    OnlineMarketerMixColumns.Add(
        new DataGridTextColumn
        {
            Header = string.Format("ColumnNumber"+i),
            Binding = new Binding(string.Format("[{0}]", i))
            {
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            },
        });
}