【问题标题】:DataTrigger referencing an enum DependencyProperty引用枚举 DependencyProperty 的 DataTrigger
【发布时间】:2016-07-31 02:15:05
【问题描述】:

解决方法:请看宜兰回答!

我目前正在开发一些自定义控件,这就是其中之一。根据DirectionProperty,我想用DataTrigger 改变linearGradientBrush 的方向。我真的无法让它工作并希望得到您的帮助。

DataTrigger 似乎无法真正获取值或方向。提前致谢 圣荷罗

编辑:这样做我得到一个错误:

System.Windows.Data 错误:4:找不到与引用“RelativeSource FindAncestor,AncestorType='CustomControlLibrary.ColoredProgress',AncestorLevel='1''的绑定源。绑定表达式:路径=方向;数据项=空;目标元素是'ColoredProgress'(名称='');目标属性是“NoTarget”(类型“对象”)

C#

using System.Windows;
using System.Windows.Controls;

namespace CustomControlLibrary
{
    public class ColoredProgress : Control
    {
        public enum colorDirection { Increase, Decrease }

        private static DependencyProperty ProgressProperty =
            DependencyProperty.Register("Progress", typeof(double), typeof(ColoredProgress), new PropertyMetadata(0.00));

        private static DependencyProperty DirectionProperty =
            DependencyProperty.Register("Direction", typeof(colorDirection), typeof(ColoredProgress), new PropertyMetadata(colorDirection.Increase));

        public double Progress
        {
            get { return (double)GetValue(ProgressProperty); }
            set { SetValue(ProgressProperty, converter(value)); }
        }

        public colorDirection Direction
        {
            get { return (colorDirection)GetValue(DirectionProperty); }
            set { SetValue(DirectionProperty, value); }
        }

        public ColoredProgress()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ColoredProgress), new FrameworkPropertyMetadata(typeof(ColoredProgress)));
            this.Loaded += ColoredProgress_Loaded;
        }

        private void ColoredProgress_Loaded(object sender, RoutedEventArgs e)
        {
            double height = (double)GetValue(ColoredProgress.ActualHeightProperty);
            SetValue(ProgressProperty, height - (height * Progress));
        }

        //takes a double between 0-1 (percent of the ProgressBar) and converts it to the value needed in the design
        private double converter(double percentage)
        {
            double height = (double)GetValue(ColoredProgress.ActualHeightProperty);
            return height - (height * percentage);
        }
    }
}

XAML

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:CustomControlLibrary">

    <Style TargetType="{x:Type local:ColoredProgress}">

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ColoredProgress}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            RenderTransformOrigin="0.5, 0.5"
                            DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ColoredProgress}}}">

                        <Grid x:Name="PART_Bar">
                            <Grid Background="Transparent" Panel.ZIndex="1">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <Rectangle Fill="{TemplateBinding Background}" Height="{Binding Path=Progress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                            </Grid>

                            <Grid Panel.ZIndex="0">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*" x:Name="increase"/>
                                    <RowDefinition Height="0" x:Name="decrease"/>
                                </Grid.RowDefinitions>
                                <Rectangle Grid.Row="0">
                                    <Rectangle.Fill>
                                        <LinearGradientBrush StartPoint="0.5,1" EndPoint="0.5,0">
                                            <GradientStop Color="Yellow" Offset="0.0" />
                                            <GradientStop Color="Red" Offset="1.0" />
                                        </LinearGradientBrush>
                                    </Rectangle.Fill>
                                </Rectangle>
                                <Rectangle Grid.Row="1">
                                    <Rectangle.Fill>
                                        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                                            <GradientStop Color="Yellow" Offset="0.0" />
                                            <GradientStop Color="Red" Offset="1.0" />
                                        </LinearGradientBrush>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </Grid>
                        </Grid>
                    </Border>

                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding Path=Direction, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ColoredProgress}}}" Value="colorDirection.Decrease">
                            <Setter TargetName="increase" Property="Height" Value="0"/>
                            <Setter TargetName="decrease" Property="Height" Value="*"/>
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

【问题讨论】:

    标签: wpf xaml triggers wpf-controls dependency-properties


    【解决方案1】:

    请使用常规触发器:

                    <ControlTemplate TargetType="{x:Type local:ColoredProgress}">
                    ...
    
                    <ControlTemplate.Triggers>
                        <Trigger Property="Direction" Value="Decrease">
                            <Setter TargetName="increase" Property="Height" Value="0"/>
                            <Setter TargetName="decrease" Property="Height" Value="*"/>
                        </Trigger>
                        <Trigger Property="Direction" Value="Increase">
                            <Setter TargetName="increase" Property="Height" Value="*"/>
                            <Setter TargetName="decrease" Property="Height" Value="0"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
    

    据我了解,数据触发器转到 DataContext 以检查该值,因为您已将 Direction 定义为控件的依赖属性,因此您可以直接获取该值。此外,您无法指向数据上下文,因为您的数据上下文中没有任何属性可以为您提供所需的值。这就是您收到绑定表达式错误的原因。 如果您需要更多解释,请告诉我。

    问候。

    【讨论】:

    • @Ilan 感谢您的快速回复!也为我工作。您的回答完全可以理解,再次感谢!
    【解决方案2】:

    我还没有运行您的代码,但我想您的问题是您在 DataTrigger 中的值绑定未正确设置为您期望的 Enum 值。

    试试这个:(注意新的 Value 绑定)

    <ControlTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=Direction, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ColoredProgress}}}" 
                     Value="{x:Static local:colorDirection.Decrease}">
            <Setter TargetName="increase" Property="Height" Value="0"/>
            <Setter TargetName="decrease" Property="Height" Value="*"/>
        </DataTrigger>
    </ControlTemplate.Triggers>
    

    我想它应该可以工作,但我没有检查其余代码,所以请随时在此处更新您的进度。

    【讨论】:

    • 我收到一个错误:CustomControlLibrary 中没有名称 colorDirection。我如何引用它?
    • 由于colorDirection 是一个嵌套枚举,您需要使用包含类限定符(我认为?)Value="{x:Static local:ColoredProgress.colorDirection.Decrease}"
    • 好吧,尝试在自定义控件之外声明枚举,在同一个命名空间中。由于枚举无论如何都用作控件中的公共属性,因此在单独的文件中声明它会更合适。
    • 访问嵌套元素的语法如下:Value="{x:Static local:ColoredProgress+colorDirection.Decrease}"
    猜你喜欢
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 2017-08-31
    • 1970-01-01
    • 2010-12-02
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多