Tho*_*que 5 wpf itemscontrol itemssource
我正在编写一个自定义ItemsControl(标签式文档容器),当用户关闭它时,每个项目(选项卡)都可以从UI中删除.但是,我不能直接从ItemsControl.Items集合中删除它,因为这些项可以是数据绑定.所以,我必须从删除它ItemsSource,它可以是任何东西(ICollection,DataTable,DataSourceProvider...).
在我的应用程序的上下文中,我知道它的实际类型是什么ItemsSource,但我希望该控件更通用,以便我可以在以后重用它.
所以我正在寻找一种从数据源中删除项目的方法,而不知道它的类型.我可以使用反射,但感觉很脏......到目前为止,我想出的最佳解决方案是使用dynamic:
internal void CloseTab(TabDocumentContainerItem tabDocumentContainerItem)
{
// TODO prompt user for confirmation (CancelEventHandler ?)
var item = ItemContainerGenerator.ItemFromContainer(tabDocumentContainerItem);
// TODO find a better way...
try
{
dynamic items = ItemsSource;
dynamic it = item;
items.Remove(it);
}
catch(RuntimeBinderException ex)
{
Trace.TraceError("Oops... " + ex.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
但我对此并不满意,我相信一定有更好的方法.任何建议,将不胜感激 !
该ItemCollection由归国ItemsControl.Items不会允许你直接调用删除,但它实现IEditableCollectionView并不会允许你调用该接口的Remove方法.
这仅在集合视图绑定到ItemsSource实现IEditableCollectionView自身时才有效.默认集合视图适用于大多数可变集合,但不适用于实现ICollection但不适用的对象IList.
IEditableCollectionView items = tabControl.Items; //Cast to interface
if (items.CanRemove)
{
items.Remove(tabControl.SelectedItem);
}
Run Code Online (Sandbox Code Playgroud)
好吧,我找到了解决方案...
如果ItemsSource是数据绑定的,我要么引发一个事件(与代码隐藏一起使用),要么调用一个命令(与 ViewModel 一起使用)来从ItemsSource集合中删除该项目。
如果不是数据绑定,我会引发一个事件来提示用户确认,然后直接从Items
public static readonly DependencyProperty CloseTabCommandProperty =
DependencyProperty.Register(
"CloseTabCommand",
typeof(ICommand),
typeof(TabDocumentContainer),
new UIPropertyMetadata(null));
public ICommand CloseTabCommand
{
get { return (ICommand)GetValue(CloseTabCommandProperty); }
set { SetValue(CloseTabCommandProperty, value); }
}
public event EventHandler<RequestCloseTabEventArgs> RequestCloseTab;
public event EventHandler<TabClosingEventArgs> TabClosing;
internal void CloseTab(TabDocumentContainerItem tabDocumentContainerItem)
{
if (ItemsSource != null) // Databound
{
object item = ItemContainerGenerator.ItemFromContainer(tabDocumentContainerItem);
if (item == null || item == DependencyProperty.UnsetValue)
{
return;
}
if (RequestCloseTab != null)
{
var args = new RequestCloseTabEventArgs(item);
RequestCloseTab(this, args);
}
else if (CloseTabCommand != null)
{
if (CloseTabCommand.CanExecute(item))
{
CloseTabCommand.Execute(item);
}
}
}
else // Not databound
{
if (TabClosing != null)
{
var args = new TabClosingEventArgs(tabDocumentContainerItem);
TabClosing(this, args);
if (args.Cancel)
return;
}
Items.Remove(tabDocumentContainerItem);
}
}
Run Code Online (Sandbox Code Playgroud)