如何使绑定的DataGrid具有空行而不反映在绑定源中

时间:2016-06-01 06:45:37

标签: c# wpf data-binding datagrid

我有DataGrid通过ItemsSource绑定到数据源。

<DataGrid ItemsSource="{Binding MyData}" ...

private ObservableCollection<Data> myData = null;
public ObservableCollection<Data> MyData
{
    get
    {
        if (myData == null)
            myData = new ObservableCollection<Data>();

        return myData;
    }
}

这些是我的要求。

  1. 此数据网格在首次加载时需要有几个空行(没有任何数据),即使稍后加载了其他数据,这些空行也将始终位于数据网格的底部。
  2. 这些空行不得反映在源集合(MyData)。原因是源集合被程序的其他部分使用。
  3. 空行允许用户在任何空行上通过双击添加新的“模板”Data; “template”在这里表示具有预定义属性集的Data对象(尽管非空)。
  4. 此项目不遵循MVVM,因此可以打破MVVM的任何甚至所有规则。
  5. 我知道要求可能看起来很愚蠢,但这些是我需要满足的要求,无论愚蠢与否。我更愿意以更恰当的方式做到这一点,但我与这些要求联系在一起,我无能为力。

    任何建议都表示赞赏。感谢。

    修改

    嗯,我实际上自己想出了一个解决方案。我通过订阅原始的ObservableCollection的CollectionChanged事件创建了另一个反映原始属性的属性。

    private static object _emptyData = new object();
    private ObservableCollection<object> myClonedData =
        new ObservableCollection<object>() { _emptyData, _emptyData, _emptyData };
    public ObservableCollection<object> MyClonedData
    {
        get
        {
            return myClonedData;
        }
        private set
        {
            if (myClonedData != value)
            {
                myClonedData = value;
                OnPropertyChanged("MyClonedData");
            }
        }
    }
    
    private void MyData_OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach (var newitem in e.NewItems)
            {
                MyClonedData.Insert(MyClonedData.Count - 3, newitem);
            }
            OnPropertyChanged("MyClonedData");
        }
        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            foreach (var newitem in e.NewItems)
            {
                MyClonedData.Remove(newitem);
            }
            OnPropertyChanged("MyClonedData");
        }
    }
    
    public ObservableCollection<Data> MyData
    {
        get
        {
            if (myData == null)
                myData = new ObservableCollection<Data>();
    
            return myData;
        }
        set
        {
            if (value != myData)
            {
                if (myData != null)
                    myData.CollectionChanged -= MyData_OnCollectionChanged;
                value.CollectionChanged += MyData_OnCollectionChanged;
    
                myData = value;
                OnPropertyChanged("MyData");
    
                MyClonedData = new ObservableCollection<object>()
                    { _emptyData, _emptyData, _emptyData };
            }
        }
    }
    

    考虑到我使用setter来做多少事情,可能不是很优雅,但它确实有效。我仍在寻找更好的替代品。

    编辑2

    我改写了一些我的要求,因为它们不太清楚。还要在以前的编辑中回答Kylo关于我自己的解决方案。在该解决方案中,我创建了另一个属性(MyClonedData集合),我的数据网格可以绑定该属性,并且该集合是原始MyData集合的克隆。这样,空行通过通用Object实例添加,但仅添加到克隆的集合中。这样,我的原始集合不受影响,因此我的程序的其他部分可以访问和处理它。

1 个答案:

答案 0 :(得分:0)

更改您的属性MyData get方法,如下所示:

 private ObservableCollection<Data> myData = null;
    public ObservableCollection<Data> MyData
    {
        get
        {
            if (myData == null)
                myData = new ObservableCollection<Data>();
            if (myData != null)
            {
                myData = new ObservableCollection<MyClass>(myData.Where(x => !string.IsNullOrEmpty(x.Name)));
                //If Class Data has property Name
                //Additional consitions also can be added in where clause
            }
            return myData;
        }
    }

但我建议您在需要时通过方法更好地过滤掉这个集合。