【问题标题】:How to change visualstate values and reuse the control with different properties values?如何更改视觉状态值并重用具有不同属性值的控件?
【发布时间】:2020-10-05 21:07:51
【问题描述】:

我已经实现了一个自定义文本框,它可以在 MouseOver 事件上更改 BorderBrush(在这种情况下,它会更改 BorderBrush,但我可以更改其他属性)。

现在,如果我想自定义 MouseOver 上的 BorderBrush 的颜色并使用不同的“BorderBrush on MouseOver”颜色创建不同的文本框,如何使用视觉状态来做到这一点? 有没有办法不为每个文本框定义不同的样式?

<ResourceDictionary>

    <Style TargetType="{x:Type local:IconTextBox}">
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="BorderBrush" Value="Black"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:IconTextBox}">
                    <Border x:Name="Border"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="0:0:0.5" />
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <ColorAnimationUsingKeyFrames
                                            Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
                                            Storyboard.TargetName="Border">
                                            <EasingColorKeyFrame KeyTime="0"
                                                Value="Green" />
                                                <!-- I want to change that Green -->

                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <ScrollViewer x:Name="PART_ContentHost"
                                    Focusable="False"
                                    HorizontalScrollBarVisibility="Hidden"
                                    VerticalScrollBarVisibility="Hidden" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

【问题讨论】:

    标签: wpf triggers custom-controls reusability visualstatemanager


    【解决方案1】:

    您不需要单独的样式来更改颜色。您可以向 IconTextBox 添加依赖属性并根据该属性更改颜色。

    在 IconTextBox.cs 中声明一个依赖属性:

    public Color MouseOverBorderBrushColor
    {
        get { return (Color)GetValue(MouseOverBorderBrushColorProperty); }
        set { SetValue(MouseOverBorderBrushColorProperty, value); }
    }
    
    public static readonly DependencyProperty MouseOverBorderBrushColorProperty =
        DependencyProperty.Register("MouseOverBorderBrushColor", typeof(Color), 
        typeof(IconTextBox), new PropertyMetadata(null));
    

    以您的风格绑定到属性:

    <ControlTemplate TargetType="{x:Type local:IconTextBox}">
        <Border x:Name="Border"
            BorderThickness="{TemplateBinding BorderThickness}"
            BorderBrush="{TemplateBinding BorderBrush}"
            Background="{TemplateBinding Background}">
            <Border.Resources>
                <ResourceDictionary>
                    <Storyboard x:Key="ColorStoryboard">
                        <ColorAnimationUsingKeyFrames
                        Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
                        Storyboard.TargetName="Border">
                            <EasingColorKeyFrame KeyTime="0"
                            Value="{Binding MouseOverBorderBrushColor, RelativeSource={RelativeSource TemplatedParent}}" />
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                </ResourceDictionary>
            </Border.Resources>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualStateGroup.Transitions>
                        <VisualTransition GeneratedDuration="0:0:0.5" />
                    </VisualStateGroup.Transitions>
                    <VisualState x:Name="Normal" />
                    <VisualState x:Name="MouseOver" Storyboard="{StaticResource ColorStoryboard}" />
    
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
    
            <ScrollViewer x:Name="PART_ContentHost"
                Focusable="False"
                HorizontalScrollBarVisibility="Hidden"
                VerticalScrollBarVisibility="Hidden" />
        </Border>
    </ControlTemplate>
    

    请注意,您不能在 VisualStateManager 中使用 TemplatedParent,因此我将情节提要作为静态资源添加到边框资源中并在 VisualStateManager 中使用。这个技巧解释了here

    然后您可以使用不同的鼠标悬停边框刷颜色的 IconTextBoxes:

    <local:IconTextBox MouseOverBorderBrushColor="Green" />
    <local:IconTextBox MouseOverBorderBrushColor="Red" />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-12
      • 1970-01-01
      相关资源
      最近更新 更多