作为一个序言,这个问题来自于扩展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>
而这一切都很好地产生这样的:
现在,当我更改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
继承的自定义控制,所以我有机会获得保护的方法(这是怎样的作品上面代码的最后一行)。我只是将这部分提取出来以提供一小部分可重现代码。
在这一点上,我不知道还有什么要尝试。那么,我怎么能强制我的绑定更新,基于我如何做呢?
尝试直接绑定到ComboBox.Tag,就像这样:{绑定的RelativeSource = {的RelativeSource FindAncestor,AncestorType = {X:类型组合框}},路径=标签} – Evk
@Evk,我不能这样做,因为我不不想要标签中的实际内容。我想使用标签中的内容使其成为其他内容。因此转换器。 – David
我明白了,但我的意思是代替这个“ ”,如上所述直接绑定到Tag(但仍使用多重绑定)。虽然不确定为什么使用多重绑定,但在转换器中只使用第一个参数,所以您可以使用常规的转换器绑定。 –
Evk