DataTrigger引用枚举DependencyProperty

时间:2016-04-09 21:28:06

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

解决方案:请看Ilan的答案!

我目前正在开发一些CustomControls,这就是其中之一。根据DirectionProperty,我想用DataTrigger更改linearGradientBrush的方向。我真的无法让它发挥作用并希望得到你的帮助。

看起来DataTrigger并不能真正获得价值或方向。提前致谢 SanHolo

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

System.Windows.Data错误:4:无法找到带引用的绑定源' RelativeSource FindAncestor,AncestorType =' CustomControlLibrary.ColoredProgress',AncestorLevel =' 1'& #39 ;. BindingExpression:路径=方向;的DataItem = NULL;目标元素是< ColoredProgress' (名称='&#39);目标财产是“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>

2 个答案:

答案 0 :(得分: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定义为控件的依赖属性,可以直接获取值。除此之外,您无法指出数据上下文,因为您在数据上下文中没有任何属性可以为您提供所需的值。这就是你得到绑定表达式错误的原因。 如果您需要更多解释,请告诉我。

问候。

答案 1 :(得分:0)

我没有运行您的代码,但我认为您的问题是 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>

我认为它应该可行,但我没有检查其余的代码,所以请随时更新您的进度。