簡體   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