[英]Setting Label.Content to Control on DataTrigger
最近,我尝试制作标签样式,该样式将允许显示图像或文本块,具体取决于是否设置了属性。 我已经将适当的对象绑定到标签的DataContext并为这些标签准备了可重用的样式。 默认内容为文本块,其名称为Name,但如果IsIconSet属性为true,则内容将变为具有相应IconPath作为源的图像。
类似的方法可以完美地与标签的属性(例如背景或光标)配合使用,但是在上述情况下,当IsIconSet在两个实例中具有相同的值时,该方法就会中断。 然后,它对第一个标签不显示任何内容,而对第二个标签显示正确的文本块/图像。
我尝试以样式将转换器附加到Name和IconPath绑定,以检查正在传递的值,但似乎甚至没有在第一个标签上调用它。
有没有人设法做类似的事情? 我缺少基本的东西吗? 也许还有另一种方法来处理这种行为? 任何帮助将不胜感激。
简化代码:
主窗口
<StackPanel DataContext="{Binding First}">
<Label Style="{StaticResource LabelStyle}" />
</StackPanel>
<StackPanel DataContext="{Binding Second}">
<Label Style="{StaticResource LabelStyle}" />
</StackPanel>
样式
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="Content">
<Setter.Value>
<TextBlock Text="{Binding Name}"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsIconSet}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="{Binding IconPath}"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
班级
public class ViewModel : INotifyPropertyChanged
{
private LabelClass _first;
private LabelClass _second;
public LabelClass First
{
get => _first;
set
{
_first = value;
OnPropertyChanged();
}
}
public LabelClass Second
{
get => _second;
set
{
_second = value;
OnPropertyChanged();
}
}
public ViewModel()
{
First = new LabelClass("First", "Resources/first.png");
Second = new LabelClass("Second", "Resources/second.png");
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class LabelClass : INotifyPropertyChanged
{
private string _name;
private string _iconPath;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged();
}
}
public string IconPath
{
get => _iconPath;
set
{
_iconPath = value;
OnPropertyChanged();
OnPropertyChanged("IsIconSet");
}
}
public bool IsIconSet => !string.IsNullOrEmpty(IconPath);
public LabelClass(string name, string iconPath = null)
{
Name = name;
IconPath = iconPath;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
LabelStyle可以由多个Label使用,但是TextBlock和Content setter中的Image只能创建一次,所有标签只有一个实例,但是不能在多个位置显示。 因此它仅显示在一个中。
要解决此问题,请使用ContentTemplate,如下所示。
<Setter Property="Content" Value="{Binding}"/>
行表示整个DataContext被视为标签内容。 对于ContentTemplate中的绑定是必需的
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="Content" Value="{Binding}"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsIconSet}" Value="True">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Source="{Binding IconPath}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
或者,将TextBlock和Image转换为非共享资源:
<Image Source="{Binding IconPath}" x:Key="Img" x:Shared="False"/>
<TextBlock Text="{Binding Name}" x:Key="Txt" x:Shared="False"/>
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="Content" Value="{StaticResource Txt}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsIconSet}" Value="True">
<Setter Property="Content" Value="{StaticResource Img}"/>
</DataTrigger>
</Style.Triggers>
</Style>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.