0

我有一个绑定到Dictionary<string, DataTable>. 选项卡名称绑定到字典Keys,选项卡内容绑定到DataTables. 这一切都很好,但在构建后的某个未指定的点,所有表都被重建为一个更大更复杂的表。我的问题是如何提供更改通知以便 WPF 正确更新表?

这似乎是一件很明显的事情,我想知道我是否遗漏了什么,或者我真的需要使用可观察的字典构造或带有更改通知的自定义 DataTable 包装器?

到目前为止我尝试过的解决方案:

  • 使用ObservableCollection< KeyValuePair<string, DataTable>并添加或删除条目。这实际上工作正常,但最终会导致在表格需要更新时选项卡消失和重新出现的视觉效果不佳

  • 我显然可以使用代码隐藏来破解它,但如果可能的话,我想避免这种情况。

这是 XAML

<TabControl ItemsSource="{Binding StringToDataTableDictionary}" >
  <TabControl.ItemTemplate>
    <DataTemplate>
      <Label Content="{Binding Key}" />
    </DataTemplate>
  </TabControl.ItemTemplate>
  <TabControl.ContentTemplate>
    <DataTemplate>
      <igDP:XamDataGrid DataSource="{Binding Path=Value}"
    </DataTemplate>
  </TabControl.ContentTemplate>
</TabControl>
4

2 回答 2

0

因此,归根结底,您需要一个实现INotifyCollectionChangedIEnumerable(例如ObservableCollection,或ICollectionView)的类。当然,你也可以自己编一个。主要的是您在类中实现这两个接口,然后CollectionChanged在集合更改时调用。

一个简单的例子:

class MyObservableDictionary<T, U> : INotifyCollectionChanged, IEnumerable
{
    Dictionary<T, U> items = new Dictionary<T,U>();

    public void Add(T key, U value)
    {
        this.items.Add(key, value);

        // Update any listeners
        if (CollectionChanged != null)
            CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    // This is from implementing INotifyCollectionChanged
    public event NotifyCollectionChangedEventHandler CollectionChanged;

    // This is from implementing IEnumerable
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        // Dump the entire collection into a 'yield return'. C# will automatically
        // build an enumerator class from it.
        foreach (KeyValuePair<T, U> item in items)
            yield return item;
    }
}

如您所见,当我添加一个项目时,我确保它CollectionChanged不为空(也就是说,有人正在监视这个类的集合更改),然后我调用它。这会提示监控对象调用GetEnumerator. 在该GetEnumerator函数中,我只为每个项目执行一个并“返回”每个项目(它告诉 c# 自动构建一个枚举器,所以我不必自己做)。

XAML:

<ListBox ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Label Content="{Binding Key}" FontWeight="Bold"/>
                <Label Content="{Binding Value}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
于 2013-02-06T13:39:52.627 回答
0

最后,没有收集通知机制解决了我的问题。我猜这是因为在幕后,WPF 持有对 DataTable 的引用,这就是需要提供更改通知的引用。我意识到我可以删除该表并将其重新添加到集合中,但这会导致 GUI 速度过慢。因此,我构建了一个提供更改通知的 DataTable 包装器,请参见此处:

public class DataTableWithNotification : INotifyPropertyChanged
{
    private DataTable _theTable = new DataTable();

    public DataTableWithNotification()
    {
    }

    public DataTableWithNotification(DataTable dt)
    {
        _theTable = dt;
    }

    public DataTable Table
    {
        get { return _theTable; }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void ChangeTableAndNotify(DataTable newTable)
    {
        _theTable = newTable;

        OnPropertyChanged("Table");
    }

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}
于 2013-04-17T11:34:15.360 回答