繁体   English   中英

筛选后的组合框ItemsSource绑定问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM