繁体   English   中英

设置Label.Content以控制DataTrigger

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM