2016-11-08 59 views
3

作爲一個序言,這個問題來自於擴展this answer關於如何使所選項目與ComboBox中的下拉項目看起來不同。如何在一個ComboBox TemplateSelector內部強制WPF多重綁定更新?

我試圖讓我的自定義選擇的項目使用信息從ComboBox的標籤屬性。由於我需要使用轉換器,因此我使用mutli-converter以便能夠將「我自己」發送到轉換類。因此,我有這兩個模板:

<DataTemplate x:Key="SelectedItemTemplate"> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock> 
      <TextBlock.Text> 
       <MultiBinding Converter="{StaticResource SelectedConverter}"> 
        <Binding RelativeSource="{RelativeSource Self}" /> 
        <Binding StringFormat="This is here so it's called every time" /> 
       </MultiBinding> 
      </TextBlock.Text> 
     </TextBlock> 
     <TextBlock Text="{Binding}" /> 
    </StackPanel> 
</DataTemplate> 

<DataTemplate x:Key="DropDownItemsTemplate"> 
    <TextBlock Grid.Column="0" Text="{Binding}" Margin="0,0,10,0" VerticalAlignment="Center" /> 
</DataTemplate> 

我的轉換器:

class SelectedConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     var retVal = ""; 

     // The value passed in should be the TextBox in the ComboBoxItem 
     var element = values[0] as DependencyObject; 

     // Try to find it's parent RoleComboBox 
     while (element != null && !(element is ComboBox)) 
     { 
      element = VisualTreeHelper.GetParent(element); 
     } 

     // If we didn't find anything, return an empty string 
     if (element == null) return retVal; 

     // Otherwise, get the role from the ComboBox 
     var tag = (element as ComboBox).Tag; 

     if (tag?.ToString().Contains("Custom") ?? false) 
     { 
      retVal = "Custom Stuff "; 
     } 

     return retVal; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

XAML組合框

<ComboBox Name="myComboBox" Grid.Column="0" Tag="My Custom Tag" ItemTemplateSelector="{StaticResource CbTemplateSelector}"> 
    <ComboBox.Items> 
     <ComboBoxItem Content="A" /> 
     <ComboBoxItem Content="B" /> 
     <ComboBoxItem Content="C" /> 
     <ComboBoxItem Content="D" /> 
     <ComboBoxItem Content="E" /> 
    </ComboBox.Items> 
</ComboBox> 

而這一切都很好地產生這樣的:

Screen Snip

現在,當我更改Tag屬性時,我需要做的是將「Custom Stuff C」更改爲其他內容。到目前爲止,它只會改變,當我改變選擇的項目,但我需要它改變,用戶不得不改變它到D,然後回到C.

從reserach,我試過迫使更新與下面的代碼,但它不起作用。

myComboBox.GetBindingExpression(ComboBox.ItemTemplateProperty)?.UpdateTarget(); 
myComboBox.GetBindingExpression(ComboBox.ItemTemplateSelectorProperty)?.UpdateTarget(); 
myComboBox.GetBindingExpression(ComboBox.SelectionBoxItemTemplateProperty)?.UpdateTarget(); 
myComboBox.GetBindingExpression(ComboBox.TemplateProperty)?.UpdateTarget(); 
myComboBox.UpdateLayout(); 
myComboBox.OnSelectionChanged(new SelectionChangedEventArgs(SelectionChangedEvent, new List<bool> { }, new List<bool> { })); 

注意,其實我確實有從ComboBox繼承的自定義控制,所以我有機會獲得保護的方法(這是怎樣的作品上面代碼的最後一行)。我只是將這部分提取出來以提供一小部分可重現代碼。

在這一點上,我不知道還有什麼要嘗試。那麼,我怎麼能強制我的綁定更新,基於我如何做呢?

+1

嘗試直接綁定到ComboBox.Tag,就像這樣:{綁定的RelativeSource = {的RelativeSource FindAncestor,AncestorType = {X:類型組合框}},路徑=標籤} – Evk

+0

@Evk,我不能這樣做,因爲我不不想要標籤中的實際內容。我想使用標籤中的內容使其成爲其他內容。因此轉換器。 – David

+0

我明白了,但我的意思是代替這個「」,如上所述直接綁定到Tag(但仍使用多重綁定)。雖然不確定爲什麼使用多重綁定,但在轉換器中只使用第一個參數,所以您可以使用常規的轉換器綁定。 – Evk

回答

2

而是結合自身,然後在代碼中搜索父組合框,只需使用內置的方法來做到這一點:

<TextBlock.Text> 
    <MultiBinding Converter="{StaticResource SelectedConverter}"> 
     <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}" Path="Tag" /> 
     <Binding StringFormat="This is here so it's called every time" /> 
    </MultiBinding> 
</TextBlock.Text> 

作爲獎勵,如果你直接綁定到ComboBox.Tag - 全multibinding將在標籤更改時刷新。