二维 ReadOnlyObservableCollection

Two dimensional ReadOnlyObservableCollection

我想绑定 Foo.Data 属性 并且我需要它是二维的 ObservableCollection。由于我不希望 Data 属性 在 Foo class 之外更改,因此我试图将其公开为 ReadOnlyObservableCollection。但是更新封装的 _data 字段不会更新 Data 属性.

public sealed class Foo
{
    private readonly ObservableCollection<ObservableCollection<string>> _data;

    public Foo()
    {
        _data = new ObservableCollection<ObservableCollection<string>>();

        // this line gives compile time error
        // cannot convert from ObservableCollection<ObservableCollection<string>> to ObservableCollection<ReadOnlyObservableCollection<string>>
        // Data = new ReadOnlyObservableCollection<ReadOnlyObservableCollection<string>>(_data);

        // Fill the _data variable
        for (var i = 0; i<10; i++)
        {
            var t = new ObservableCollection<string>();
            for (var j = 0; j<10; j++)
            {
                t.Add(i + "+" + j);
            }
            _data.Add(t);
        }

        var tmp = new ObservableCollection<ReadOnlyObservableCollection<string>>();
        foreach (var row in _data)
        {
            tmp.Add(new ReadOnlyObservableCollection<string>(row));
        }
        Data = new ReadOnlyObservableCollection<ReadOnlyObservableCollection<string>>(tmp);
    }

    public ReadOnlyObservableCollection<ReadOnlyObservableCollection<string>> Data { get; }

    public void RemoveItem(int x, int y)
    {
        _data[x].RemoveAt(y); // This does update the Data collection.
    }

    public void RemoveRow(int x)
    {
        _data.RemoveAt(x); // This does not update the Data collection.
    }
}

这里是working sample.

仅供参考:如果您想编辑或重新运行代码,只需单击 fork。

我在网上搜索过有关它的信息,但找不到任何内容。 ObservableCollection不是二维的东西,有没有更好的做法?

RemoveRow 方法不会更新 Data 集合,因为 _dataData 无关(除了它们共享一些内容)。与 Data 相关的集合是 tmp,所以我会尝试以下操作:

  • 创建 tmp class 成员并为其命名(例如 _rowData
  • _data 重命名为 _itemData
  • RemoveRow
  • 中使用_rowData

这是结果:

public sealed class Foo
{
    private readonly ObservableCollection<ObservableCollection<string>> _itemData;
    private readonly ObservableCollection<ReadOnlyObservableCollection<string>> _rowData;

    public Foo()
    {
        _itemData = new ObservableCollection<ObservableCollection<string>>();

        // Fill the _itemData variable
        for (var i = 0; i<10; i++)
        {
            var t = new ObservableCollection<string>();
            for (var j = 0; j<10; j++)
            {
                t.Add(i + "+" + j);
            }
            _itemData .Add(t);
        }

        _rowData = new ObservableCollection<ReadOnlyObservableCollection<string>>();
        foreach (var row in _itemData )
        {
            _rowData.Add(new ReadOnlyObservableCollection<string>(row));
        }
        Data = new ReadOnlyObservableCollection<ReadOnlyObservableCollection<string>>(_rowData);
    }

    public ReadOnlyObservableCollection<ReadOnlyObservableCollection<string>> Data { get; }

    public void RemoveItem(int x, int y)
    {
        _itemData[x].RemoveAt(y);
    }

    public void RemoveRow(int x)
    {
        _rowData.RemoveAt(x);
    }
}