关于您问题的第一部分,您可以像设置文本块一样设置ContentControl 的ToolTip,如果ContentControl 为空,则不会显示工具提示。
对于TemplateSelector,只需定义两个使用Multibinding和转换器的模板(确保使用ElementName绑定属性以避免UnserValue场景),并绑定ContentTemplateSelector ContentControl 到您的DataTemplateSelector 设置为两个定义的DataTemplates,这里是如何做到这一点的完整示例:
主窗口 xaml:
<Window ...
x:Name="Main"
Title="MainWindow" Height="450" Width="800" DataContext="{Binding RelativeSource={RelativeSource Self}}" >
<Window.Resources>
<local:CountToStringConverter x:Key="CountToStringConverter"/>
<DataTemplate x:Key="FirstTemplate">
<Grid>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource CountToStringConverter}">
<Binding Path="DataContext.Property1" ElementName="Main"/>
<Binding Path="DataContext.Property2" ElementName="Main"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Grid>
</DataTemplate>
<DataTemplate x:Key="SecondTemplate">
<Grid>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource CountToStringConverter}">
<Binding Path="DataContext.Property2" ElementName="Main"/>
<Binding Path="DataContext.Property1" ElementName="Main"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Grid>
</DataTemplate>
<local:MyTemplateSelector x:Key="MyTemplateSelector" FirstDataTemplate="{StaticResource FirstTemplate}" SecondDataTemplate="{StaticResource SecondTemplate}"/>
</Window.Resources>
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ContentControl ContentTemplateSelector="{StaticResource MyTemplateSelector}">
<ContentControl.ToolTip>
<MultiBinding Converter="{StaticResource CountToStringConverter}">
<Binding Path="Property1"/>
<Binding Path="Property2" />
</MultiBinding>
</ContentControl.ToolTip>
</ContentControl>
<TextBlock Grid.Row="1">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource CountToStringConverter}">
<Binding Path="Property1"/>
<Binding Path="Property2" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Grid>
</Grid>
</Window>
模板选择器、转换器和代码隐藏:
public class MyTemplateSelector : DataTemplateSelector
{
public DataTemplate FirstDataTemplate { get; set; }
public DataTemplate SecondDataTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
// select your template based on item
return (new Random()).Next(2)==0?SecondDataTemplate:FirstDataTemplate;
}
}
public class CountToStringConverter:IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null)
return null;
return values[0]?.ToString() + values[1]?.ToString();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public partial class MainWindow : Window, INotifyPropertyChanged
{
private string _property1;
public string Property1
{
get { return _property1; }
set
{
if (value == _property1) return;
_property1 = value;
OnPropertyChanged();
}
}
private string _property2;
public string Property2
{
get { return _property2; }
set
{
if (value == _property2) return;
_property2 = value;
OnPropertyChanged();
}
}
public MainWindow()
{
InitializeComponent();
Property1 = "Property 1";
Property2 = "Property 2";
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
更新
正如我所说,使用 DataTriggers 应该更容易做到这一点,因此为每个图标定义一个 DataTrigger,并根据 property1 和 property2 的值使用相同的值设置 ContentTemplate多值转换器:
假设您有两个这样定义的 DataTemplate:
<Window.Resources>
<DataTemplate x:Key="WarningIconImageTemplate">
<StackPanel>
<TextBlock Text="Some Text"></TextBlock>
<Image Source="/Icons/warningIcon.png"></Image>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="CautionIconImageTemplate">
<StackPanel>
<TextBlock Text="Some Other Text"></TextBlock>
<Image Source="/Icons/cautionIcon.png"></Image>
</StackPanel>
</DataTemplate>
<local:CountToStringConverter x:Key="CountToStringConverter"/>
</Window.Resources>
您的 DataTrigger 应该如下所示:
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource CountToStringConverter}">
<Binding Path="Property1"/>
<Binding Path="Property2" />
</MultiBinding>
</DataTrigger.Binding>
<DataTrigger.Value>
<system:String>Property 1Property 2</system:String>
<!--update based on your need-->
</DataTrigger.Value>
<Setter Property="ContentTemplate" Value="{StaticResource WarningIconImageTemplate}"/>
<Setter Property="ToolTip" Value="First ToolTip"/>
</DataTrigger>
<DataTrigger >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource CountToStringConverter}">
<Binding Path="Property1"/>
<Binding Path="Property2" />
</MultiBinding>
</DataTrigger.Binding>
<DataTrigger.Value>
<system:String>Property 2Property 1</system:String>
<!--update based on your need-->
</DataTrigger.Value>
<Setter Property="ContentTemplate" Value="{StaticResource CautionIconImageTemplate}"/>
<Setter Property="ToolTip" Value="Second ToolTip"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
现在,如果您想绑定图标,您可以随时使用 ElementName 绑定:
<Window.Resources>
<DataTemplate x:Key="WarningIconImageTemplate">
<StackPanel>
<TextBlock Text="Some Text"></TextBlock>
<Image Source="{Binding DataContext.WarningImageSource,ElementName=Main}" ></Image>
</StackPanel>
</DataTemplate>
</Window.Resources>
您还可以考虑的另一个选项是在IconImageTemplate 中定义DataTrigger。