【问题标题】:c# / WPF Use of c# variable in Ressource Dictionary data triggerc# / WPF 在资源字典数据触发器中使用 c# 变量
【发布时间】:2017-05-18 09:24:00
【问题描述】:

我正在使用一些带有模板内容的按钮

例如

button.Template = (ControlTemplate)FindResource("StatusEmpty");

在文件后面的同一代码中有一个名为 currentNumber 的(全局)字段

private int currentNumber = 1;
    public int CurrentNumber
    {
        get
        {
            return currentNumber;
        }
    }

这些模板在合并的 RessourceDictionary 中定义

<ControlTemplate x:Key="BinStatusEmpty" TargetType="Button">
    <Border x:Name="border"  BorderBrush="LightGray" CornerRadius="8,8,8,8" Margin="3" >
        <Border.Background>
            <LinearGradientBrush>
                <GradientStop Offset="0" Color="white"></GradientStop>
                <GradientStop Offset="1" Color="LightGray"></GradientStop>
            </LinearGradientBrush>
        </Border.Background>
        <ContentPresenter Content = "{TemplateBinding Content}" 
           HorizontalAlignment = "Center" VerticalAlignment = "Center"  
                             TextBlock.FontSize="40"/>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="BorderBrush" Value="Blue" TargetName="border" />
            <Setter Property="BorderThickness" Value="4" TargetName="border" />
        </Trigger>

        <DataTrigger Binding="{Binding currentNumber, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" Value="{TemplateBinding Content}" >
            <Setter Property="BorderBrush" Value="Blue" TargetName="border" />
            <Setter Property="BorderThickness" Value="4" TargetName="border" />
        </DataTrigger>

    </ControlTemplate.Triggers>
</ControlTemplate>

我想要的是一个数据触发器,它根据当前c#变量改变模板动态中定义的边框。

目前有两个问题: 1)绑定

{Binding currentNumber, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}

找不到我的变量

BindingExpression path error: 'currentNumber' property not found on 'object' ''MainWindow' (Name='xMainWindow')'. BindingExpression:Path=currentNumber; DataItem='MainWindow' (Name='xMainWindow'); target element is 'BinButton' (Name=''); target property is 'NoTarget' (type 'Object')

2) 我无法绑定

{TemplateBinding Content}

作为数据触发器的值。

非常感谢

勒内

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    您应该绑定到属性 CurrentNumber(大写“C”)而不是支持字段currentNumber。

    但是您不能将DataTriggerValue 属性绑定到某个东西。不支持:

    Using binding for the Value property of DataTrigger condition

    您需要使用转换器:

    namespace WpfApplication1
    {
        public class MultiConverter : IMultiValueConverter
        {
            public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
            {
                int CurrentNumber = (int)values[0];
                object content = values[1];
    
                return CurrentNumber.ToString() == content.ToString();
            }
    
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
            {
                throw new NotSupportedException();
            }
        }
    }
    

    XAML:

    <ControlTemplate x:Key="BinStatusEmpty" TargetType="Button"
                     xmlns:local="clr-namespace:WpfApplication1">
        <ControlTemplate.Resources>
            <local:MultiConverter x:Key="conv" />
        </ControlTemplate.Resources>
        <Border x:Name="border" BorderBrush="LightGray" CornerRadius="8,8,8,8" Margin="3" >
            <Border.Background>
                <LinearGradientBrush>
                    <GradientStop Offset="0" Color="white"></GradientStop>
                    <GradientStop Offset="1" Color="LightGray"></GradientStop>
                </LinearGradientBrush>
            </Border.Background>
            <ContentPresenter Content = "{TemplateBinding Content}" 
                                      HorizontalAlignment = "Center" VerticalAlignment = "Center"  
                                    TextBlock.FontSize="40"/>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="BorderBrush" Value="Blue" TargetName="border" />
                <Setter Property="BorderThickness" Value="4" TargetName="border" />
            </Trigger>
            <DataTrigger Value="True">
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource conv}">
                        <Binding Path="CurrentNumber" RelativeSource="{RelativeSource FindAncestor, AncestorType=Window}" />
                        <Binding Path="Content" RelativeSource="{RelativeSource Self}" />
                    </MultiBinding>
                </DataTrigger.Binding>
                <Setter Property="BorderBrush" Value="Blue" TargetName="border" />
                <Setter Property="BorderThickness" Value="4" TargetName="border" />
            </DataTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    

    【讨论】:

    • 它适用于静态情况,但是当 CurrentNumber 的值发生变化时,如何实现触发器被触发?谢谢
    • @Rene:您需要实现 INotifyPropertyChanged 接口并在 CurrentNumber 属性设置为新值时引发 PropertyChanged 事件:msdn.microsoft.com/en-us/library/…
    猜你喜欢
    • 1970-01-01
    • 2011-02-09
    • 2021-12-20
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多