WPF 根据控件模板中的绑定更改图标

WPF Change icon depending on binding in Control Template

我有一个为 DevExpress TextEdit 控件定义的控件模板,我想根据绑定更改模板中的图像 Source 属性 (例如 IsIncrease)。

    <ControlTemplate x:Key="WarningTextEdit" TargetType="dxe:TextEdit">
        <Grid>
            <TextBox Text="{TemplateBinding Text}"/>
            <Image Margin="0,0,5,0" 
                   Source="pack://application:,,,/DevExpress.Xpf.Core.v17.2;component/Core/ConditionalFormatting/Images/IconSets/Symbols3_2.png" 
                   Width="17" 
                   Height="16"
                   RenderOptions.BitmapScalingMode="NearestNeighbor"   
                   HorizontalAlignment="Right"/>
        </Grid>
    </ControlTemplate>

如果 属性 IsIncrease 设置为 true,则应显示一个特定图标,如果 属性 设置为 false,则应显示另一个特定图标。有人知道怎么做吗?

谢谢

要实现这一点,您需要 2 个属性来存储 image.I 的来源,我将使用标签 属性 并编写一个附加的 属性 来存储 2 个图像来源并使用触发器来更改来源

   public class AttachedProperty
{
    public static readonly DependencyProperty AltSourceProperty =
        DependencyProperty.RegisterAttached("AltSource",
        typeof(string), typeof(AttachedProperty),
        new PropertyMetadata());

    public static string GetAltSource(DependencyObject obj)
    {
        return (string)obj.GetValue(AltSourceProperty);
    }
    public static void SetAltSource(DependencyObject obj, string value)
    {
        obj.SetValue(AltSourceProperty, value);
    }
}

控件模板

    <ControlTemplate x:Key="WarningTextEdit" TargetType="dxe:TextEdit">
            <Grid>
                <TextBox Text="{TemplateBinding Text}" />
                <Image x:Name="image"
                       Width="17"
                       Height="16"
                       Margin="0,0,5,0"
                       HorizontalAlignment="Right"
                       RenderOptions.BitmapScalingMode="NearestNeighbor" />
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsIncrease " Value="True">
                    <Setter TargetName="image" Property="Source" Value="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" />
                </Trigger>
                <Trigger Property="IsIncrease " Value="False">
                    <Setter TargetName="image" Property="Source" Value="{Binding Path=(local:AttachedProperty.AltSource), RelativeSource={RelativeSource TemplatedParent}}" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>



<dxe:TextEdit Tag="Image1.jpg" local:AttachedProperty.AltSource="Image2.jpg"/>

您可以使用转换器完成此操作,您有两种选择,要么在 Grid 中包含 2 Image,然后使用转换器 hide/show 它们,要么使用一个Image 并使用转换器更改 Source 属性(这可能是更好的解决方案)。这是一个可以处理这两种情况的转换器,其次是两种解决方案。

布尔转换器:

public class BoolConverter : MarkupExtension, IValueConverter
{
    public object TrueValue { get; set; } = Binding.DoNothing;
    public object FalseValue { get; set; } = Binding.DoNothing;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is bool))
            return Binding.DoNothing;

        return (bool)value ? TrueValue : FalseValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == TrueValue)
            return true;

        if (value == FalseValue)
            return false;

        return Binding.DoNothing;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

MainWindow.xaml(解决方案 1:两个 Image):

        <ControlTemplate x:Key="WarningTextEdit" TargetType="dxe:TextEdit">
            <Grid>
                <TextBox Text="{TemplateBinding Text}"/>
                <Image Margin="0,0,5,0" 
                       Source="pack://application:,,,/DevExpress.Xpf.Core.v17.2;component/Core/ConditionalFormatting/Images/IconSets/Symbols3_2.png" 
                       Width="17" 
                       Height="16"
                       RenderOptions.BitmapScalingMode="NearestNeighbor"   
                       HorizontalAlignment="Right"
                       Visibility="{Binding IsIncrease, Converter={local:BoolConverter TrueValue=Collapsed, FalseValue=Visible}}"/>
                <Image Margin="0,0,5,0" 
                       Source="pack://application:,,,/DevExpress.Xpf.Core.v17.2;component/Core/ConditionalFormatting/Images/IconSets/TrafficLights3_1.png" 
                       Width="17" 
                       Height="16"
                       RenderOptions.BitmapScalingMode="NearestNeighbor"   
                       HorizontalAlignment="Right"
                       Visibility="{Binding IsIncrease, Converter={local:BoolConverter TrueValue=Visible, FalseValue=Collapsed}}"/>
            </Grid>
        </ControlTemplate>

MainWindow.xaml(解决方案 2:一个 Image):

        <ControlTemplate x:Key="WarningTextEdit" TargetType="dxe:TextEdit">
            <Grid>
                <TextBox Text="{TemplateBinding Text}"/>
                <Image Margin="0,0,5,0" 
                       Source="{Binding IsIncrease, 
                                        Converter={local:BoolConverter TrueValue='pack://application:,,,/DevExpress.Xpf.Core.v17.2;component/Core/ConditionalFormatting/Images/IconSets/Symbols3_2.png', 
                                                                       FalseValue='pack://application:,,,/DevExpress.Xpf.Core.v17.2;component/Core/ConditionalFormatting/Images/IconSets/TrafficLights3_1.png'}}" 
                       Width="17" 
                       Height="16"
                       RenderOptions.BitmapScalingMode="NearestNeighbor"   
                       HorizontalAlignment="Right"/>
            </Grid>
        </ControlTemplate>