我正在尝试做什么:
我有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
的派生类,受到这些文章的启发:Building a Filtered ComboBox for WPF / WPF auto-filtering combo。
用户可以输入组合框并过滤列表以显示匹配的项目。组合框的默认行为是不合需要的(它会自动完成用户输入的内容),这就是它的派生原因。
上面的那些组合框是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的情况下应用视图
答案 0 :(得分:0)
我最终使用了相当蹩脚的解决方法,因此我仍然对智能答案感兴趣。
对于感兴趣的人:我添加了另一个类似的ItemsSource2
依赖属性(仍然没有找到一个好名字),我在其上绑定了我的项目列表,而不是原始的ItemsSource
。
当此项目来源更改时,控件将获得一个新的CollectionView
(不是默认值)并将其设置为&#34;标准&#34; 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;
}
}