我有一个绑定到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>
答案 0 :(得分:0)
因此,在一天结束时,您需要一个实现INotifyCollectionChanged
和IEnumerable
的类(例如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
不为null(也就是说,某人正在监视此类以进行集合更改),然后我调用它。这会提示监视对象调用GetEnumerator
。在GetEnumerator
函数中,我只为每个函数执行一个'并且'return return'每个项目(告诉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>
答案 1 :(得分: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));
}
}
}