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