[英]Filtered Combobox ItemsSource binding issue
我正在尝试做的是:
我有2个组合框,一个“常规”组合框和一个可过滤的组合框。 在可过滤的组合框上, ItemsSource
绑定到第一个组合框SelectedItem
的属性。
这是一些XAML来演示这种关系(我删除了一些属性):
<ComboBox Name="cbx_poche" ItemsSource="{Binding DataContext.ListePoches, ElementName=Main}" SelectedItem="{Binding PocheCible}" />
<controls:FilteredComboBox ItemsSource="{Binding SelectedItem.SupportsEligibles, ElementName=cbx_poche}" SelectedItem="{Binding Support}" />
FilteredComboBox是从ComboBox
派生的类,这些类的灵感来自那些文章: 为WPF / WPF自动筛选组合 构建Filtered ComboBox 。
用户可以在组合框中键入内容,并过滤列表以显示匹配的项目。 不需要组合框的默认行为(它会自动完成用户键入的内容),这就是派生它的原因。
上面的那些组合框位于ItemsControl
元素中,因为我需要为特定集合中的每个项目设置一行。 组合框的SelectedItem
属性绑定到此集合中的项目。
结果 :
问题 :
只要您在第一个组合框中没有选择相同的项目,它就可以很好地工作(例如上例:如果我输入的文本与上述组合不匹配,它将被重置)。
一旦将几个FilteredComboBox链接到第一个组合框中的同一项目(因此绑定到SelectedItem.SupportsEligibles
),则在FilteredComboBox中键入文本将过滤两个列表。
我知道为什么这样做,但我不知道如何解决。 所以我尝试了两件事:
代码1(当前代码):问题是代码使用列表上的默认视图,因此绑定到此列表的所有控件都将应用相同的过滤器:
protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
if (newValue != null)
{
if (ItemsSourceView != null)
ItemsSourceView.Filter -= this.FilterPredicate;
ItemsSourceView = CollectionViewSource.GetDefaultView(newValue);
ItemsSourceView.Filter += this.FilterPredicate;
}
base.OnItemsSourceChanged(oldValue, newValue);
}
代码2:因此,我的想法是从绑定视图中获取局部视图。 我可以很好地进行过滤,但是会破坏绑定(在第一次通过后更改第一个组合中的选定项不会更新列表)
protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
if (newValue != null && newValue != ItemsSourceView)
{
if (ItemsSourceView != null)
ItemsSourceView.Filter -= this.FilterPredicate;
ItemsCollectionViewSource = new CollectionViewSource { Source = newValue };
ItemsSourceView = ItemsCollectionViewSource.View;
ItemsSourceView.Filter += this.FilterPredicate;
this.ItemsSource = ItemsSourceView; // Breaks the binding !!
}
base.OnItemsSourceChanged(oldValue, newValue);
}
我被困在这里。
我正在寻找一些事件或Binding类,可以用来通知绑定更改,以便更新视图。 或者也许应用视图而不必更改ItemsSource
我最终使用了一个相当la脚的解决方法,因此我仍然对智能答案感兴趣。
对于有兴趣的人:我添加了另一个类似的ItemsSource2
Dependency属性(仍然没有为其找到一个漂亮的名称),在该属性上我绑定了我的项目列表,而不是原始的ItemsSource
。
更改此项目源后,控件将获得一个新的CollectionView
(不是默认的CollectionView
)并将其设置为“标准” ItemsSource
。
控件的其他元素保持相同(类似于链接文章中的代码)。
public static readonly DependencyProperty ItemsSource2Property =
DependencyProperty.Register(
"ItemsSource2",
typeof(IEnumerable),
typeof(FilteredComboBox),
new UIPropertyMetadata((IEnumerable)null, new PropertyChangedCallback(OnItemsSource2Changed)));
[Bindable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IEnumerable ItemsSource2
{
get { return (IEnumerable)GetValue(ItemsSource2Property); }
set
{
if (value == null)
{
ClearValue(ItemsSource2Property);
}
else
{
SetValue(ItemsSource2Property, value);
}
}
}
private static void OnItemsSource2Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ic = (FilteredComboBox)d;
var oldValue = (IEnumerable)e.OldValue;
var newValue = (IEnumerable)e.NewValue;
if (newValue != null)
{
//Prevents the control to select the first item automatically
ic.IsSynchronizedWithCurrentItem = false;
var viewSource = new CollectionViewSource { Source = newValue };
ic.ItemsSource = viewSource.View;
}
else
{
ic.ItemsSource = null;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.