分配附加属性值

时间:2016-08-21 12:27:58

标签: xaml uwp

我尝试创建附加属性,以便在状态发生变化时更改按钮背景颜色。

 [Bindable]
    public class AttachedPropertyForButton
    {
        public static Brush GetPressedBackground(DependencyObject obj)
        {
            return (Brush)obj.GetValue(PressedBackgroundProperty);
        }

        public static void SetPressedBackground(DependencyObject obj, Brush value)
        {
            obj.SetValue(PressedBackgroundProperty, value);
        }

        // Using a DependencyProperty as the backing store for PressedBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PressedBackgroundProperty =
            DependencyProperty.RegisterAttached("PressedBackground", typeof(Brush), typeof(AttachedPropertyForButton), new PropertyMetadata(null));

        public static Brush GetDisabledBackground(DependencyObject obj)
        {
            return (Brush)obj.GetValue(DisabledBackgroundProperty);
        }

        public static void SetDisabledBackground(DependencyObject obj, Brush value)
        {
            obj.SetValue(DisabledBackgroundProperty, value);
        }

        // Using a DependencyProperty as the backing store for DisabledBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DisabledBackgroundProperty =
            DependencyProperty.RegisterAttached("DisabledBackground", typeof(Brush), typeof(AttachedPropertyForButton), new PropertyMetadata(null));
    }

我用VisualStates创建了一个样式:

<Style TargetType="Button"
           x:Key="StyleButton">
        <Setter Property="Foreground"
                Value="{ThemeResource SystemControlForegroundBaseHighBrush}" />
        <Setter Property="BorderBrush"
                Value="Transparent" />
        <Setter Property="controls:AttachedPropertyForButton.PressedBackground"
                Value="#015490" />
        <Setter Property="controls:AttachedPropertyForButton.DisabledBackground"
                Value="#EBEBEB" />
        <Setter Property="BorderThickness"
                Value="0" />
        <Setter Property="Padding"
                Value="5" />
        <Setter Property="HorizontalAlignment"
                Value="Stretch" />
        <Setter Property="VerticalAlignment"
                Value="Stretch" />
        <Setter Property="VerticalContentAlignment"
                Value="Center" />
        <Setter Property="HorizontalContentAlignment"
                Value="Center" />
        <!--<Setter Property="FontFamily"
                    Value="{ThemeResource ContentControlThemeFontFamily}" />-->
        <Setter Property="FontWeight"
                Value="Normal" />
        <Setter Property="FontSize"
                Value="{ThemeResource ControlContentThemeFontSize}" />
        <Setter Property="UseSystemFocusVisuals"
                Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid x:Name="RootGrid"
                          Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                                                       Storyboard.TargetName="BorderPressed">
                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                    Value="Visible" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                                                       Storyboard.TargetName="BorderDisabled">
                                            <DiscreteObjectKeyFrame KeyTime="0"
                                                                    Value="Visible" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border x:Name="BorderPressed" 
                                Visibility="Collapsed"
                                Background="{Binding Path=(controls:AttachedPropertyForButton.PressedBackground),RelativeSource={RelativeSource TemplatedParent}}" />
                        <Border x:Name="BorderDisabled"
                                Visibility="Collapsed"
                                Background="{Binding Path=(controls:AttachedPropertyForButton.DisabledBackground),RelativeSource={RelativeSource TemplatedParent}}" />
                        <ContentPresenter x:Name="ContentPresenter"
                                          BorderBrush="{TemplateBinding BorderBrush}"
                                          BorderThickness="{TemplateBinding BorderThickness}"
                                          Content="{TemplateBinding Content}"
                                          ContentTransitions="{TemplateBinding ContentTransitions}"
                                          ContentTemplate="{TemplateBinding ContentTemplate}"
                                          Padding="{TemplateBinding Padding}"
                                          HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                          AutomationProperties.AccessibilityView="Raw" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Style的视觉状态工作正常,但是当我尝试直接在按钮实例上重新定义这些附加属性的值时 - 它不起作用,并且Visual Studio在错误列表输出中显示错误: DependencyProperty目标无效:Windows.UI.Xaml.Controls.Button 它不是编译错误,也没有运行时错误。 这段代码不起作用:

<Button  Grid.Row="6" 
     Width="{Binding ElementName=TextBoxCode, Path=ActualWidth}"
     Height="35"
     FontSize="16"
     Background="{StaticResource BrushBackground}"
     Foreground="{ThemeResource ButtonTextColor}"
     HorizontalAlignment="Center"
     Content="{Binding [TransferActivateButtonText]}"
     **controls:AttachedPropertyForButton.PressedBackground="DarkRed"**
     Command="{Binding ActivateCommand}"
     Style="{StaticResource StyleButton}"/>

1 个答案:

答案 0 :(得分:0)

它对我有用,我按原样复制你的XAML。

但我会建议略有不同的按钮样式。不需要两个Border,只需直接更改Background的{​​{1}}。

RootGrid
<Style x:Key="StyleButton" TargetType="Button">
    <!-- Default pressed and disabled backgrounds -->
    <Setter Property="controls:AttachedPropertyForButton.PressedBackground" Value="Red" />
    <Setter Property="controls:AttachedPropertyForButton.DisabledBackground" Value="Blue" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
                                        <!-- EDITED HERE -->
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding (controls:AttachedPropertyForButton.PressedBackground), RelativeSource={RelativeSource TemplatedParent}}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
                                        <!-- EDITED HERE -->
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding (controls:AttachedPropertyForButton.DisabledBackground), RelativeSource={RelativeSource TemplatedParent}}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushDisabled}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Button screenshot

(按下按钮外观)