2016-11-08 8 views
3

序文として、この質問は、選択したアイテムをコンボボックスのドロップダウンアイテムと異なるように見せる方法について、this answerを拡張したものです。ComboBox TemplateSelectorの内部でWPFマルチバインディングを強制的に更新する方法

私はComboBoxのTag属性から自分のカスタムアイテム選択情報を作成しようとしています。私はコンバーターを使う必要があるので、変換クラスに "自分"を送ることができるように私は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> 

そして、私のコンバータ:したがって、私はこれらの2つのテンプレートを持って

Screen Snip:コンボボックス

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

そして、このすべてのための

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はうまくこれを生成します

今、私がする必要があるのは、Tagプロパティを変更するときに "Custom Stuff C"を何かに変更することです。これまでのところ、選択したアイテムを変更すると変更されるだけですが、ユーザーがDに変更してCに戻らなくても変更する必要があります。

私は更新を試みました以下のコードでは動作しません。私は実際に行う

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

私は理解していますが、この代わりに ""をあなたのマルチバインディングで使用することを意味します。なぜあなたはマルチバインディングを使用するのか分かりませんが、コンバーターでは最初のパラメーターだけを使用するので、コンバーターでも通常のバインディングを使用できます。 – Evk

答えて

2

、ちょうどそれを行うにビルトインメソッドを使用します。あなたはComboBox.Tagに直接結合する場合には、ボーナスとして

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

を - 全れる多タグが変更されたときにリフレッシュされます。

関連する問題