【问题标题】:Apply Style to Button Based on Property in XAML基于 XAML 中的属性将样式应用于按钮
【发布时间】:2018-10-05 12:06:09
【问题描述】:

编辑:
也许我通过尝试交换样式使事情变得过于复杂,因为我唯一想要的就是能够根据布尔属性的状态使用不同的背景图像。问题应该更多... 如何根据布尔属性的状态为按钮使用背景图片?

当鼠标悬停在按钮上时,我有两种动画和交换图像的样式,这些样式工作正常,但我想要的是能够根据布尔属性的状态使用其中一种样式。有点像...If property equals true, use style1 otherwise use style2

这是我的代码:

动画:

     <Storyboard x:Key="MouseOverStoryboard" Duration="00:00:00.5">
        <DoubleAnimation Storyboard.TargetName="image1" Storyboard.TargetProperty="Opacity" To="0" Duration="00:00:00.3" />
        <DoubleAnimation Storyboard.TargetName="image2" Storyboard.TargetProperty="Opacity" To="1" Duration="00:00:00.3" />
    </Storyboard>

    <Storyboard x:Key="MouseLeaveStoryboard" Duration="00:00:00.5">
        <DoubleAnimation Storyboard.TargetName="image1" Storyboard.TargetProperty="Opacity" To="1" Duration="00:00:00.3" />
        <DoubleAnimation Storyboard.TargetName="image2" Storyboard.TargetProperty="Opacity" To="0" Duration="00:00:00.3" />
    </Storyboard>

样式1:

    <Style x:Key="Style1"
           TargetType="{x:Type Button}">
        <Style.Setters>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid>
                            <Image x:Name="image1" Source="Images/image.png" Stretch="None" />
                            <Image x:Name="image2" Source="Images/image-hover.png" Stretch="None" Opacity="0" />
                            <ContentPresenter />
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver"
                                     Value="True">
                                <Trigger.EnterActions>
                                    <StopStoryboard BeginStoryboardName="MouseLeaveStoryboard" />
                                    <BeginStoryboard Name="MouseOverStoryboard"
                                                     Storyboard="{StaticResource MouseOverStoryboard}" />
                                </Trigger.EnterActions>
                                <Trigger.ExitActions>
                                    <StopStoryboard BeginStoryboardName="MouseOverStoryboard" />
                                    <BeginStoryboard Name="MouseLeaveStoryboard"
                                                     Storyboard="{StaticResource MouseLeaveStoryboard}" />
                                </Trigger.ExitActions>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style.Setters>
    </Style>

风格2:

    <Style x:Key="Style2"
           TargetType="{x:Type Button}">
        <Style.Setters>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid>
                            <Image x:Name="image1" Source="Images/image2.png" Stretch="None" />
                            <Image x:Name="image2" Source="Images/image-hover2.png" Stretch="None" Opacity="0" />
                            <ContentPresenter />
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver"
                                     Value="True">
                                <Trigger.EnterActions>
                                    <StopStoryboard BeginStoryboardName="MouseLeaveStoryboard" />
                                    <BeginStoryboard Name="MouseOverStoryboard"
                                                     Storyboard="{StaticResource MouseOverStoryboard}" />
                                </Trigger.EnterActions>
                                <Trigger.ExitActions>
                                    <StopStoryboard BeginStoryboardName="MouseOverStoryboard" />
                                    <BeginStoryboard Name="MouseLeaveStoryboard"
                                                     Storyboard="{StaticResource MouseLeaveStoryboard}" />
                                </Trigger.ExitActions>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style.Setters>
    </Style>

应用样式

    <Button x:Name="MyButton"
            Command="{Binding ButtonCommand}">
            <Button.Style>
                <Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding SomeBooleanProperty}" Value="True">
                            <Setter Property="Style" Value="{StaticResource Style1}" />
                        </DataTrigger>

                        <DataTrigger Binding="{Binding SomeBooleanProperty}" Value="True">
                            <Setter Property="Style" Value="{StaticResource Style2}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
    </Button>

错误信息:

样式对象不允许影响其应用对象的样式属性。

我错过了什么?

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    我不相信这是这样做的方法。你可以在后面的代码中设置你的样式,但更好的方法是去掉 Style2 并像这样与 Style1 结合:

    <Style x:Key="Style1"
           TargetType="{x:Type Button}">
        <Style.Setters>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid>
                            <Image x:Name="image1"
                                   Source="Images/image.png" Stretch="None" />
                            <Image x:Name="image2"
                                   Source="Images/image-hover.png" Stretch="None"
                                   Opacity="0" />
                            <ContentPresenter />
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="image1" Property="Source"
                                        Value="Images/image2.png"/>
                                <Setter TargetName="image2" Property="Source"
                                        Value="Images/image-hover2.png"/>
                                <Trigger.EnterActions>
                                    <StopStoryboard BeginStoryboardName="MouseLeaveStoryboard" />
                                    <BeginStoryboard Name="MouseOverStoryboard"
                                                     Storyboard="{StaticResource MouseOverStoryboard}" />
                                </Trigger.EnterActions>
                                <Trigger.ExitActions>
                                    <StopStoryboard BeginStoryboardName="MouseOverStoryboard" />
                                    <BeginStoryboard Name="MouseLeaveStoryboard"
                                                     Storyboard="{StaticResource MouseLeaveStoryboard}" />
                                </Trigger.ExitActions>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style.Setters>
    </Style>
    

    然后你可以写:

    <Button Style="{StaticResource Style1}"/>
    

    完成。

    【讨论】:

    • 我将如何评估SomeBooleanProperty 的状态?
    【解决方案2】:

    您不能在应用于同一元素的StyleSetter 中设置en 元素的Style 属性。这基本上就是错误消息告诉您的内容。

    您可以使用单个Style 并在Style 中使用带有条件的触发器,以根据SomeBooleanProperty 属性的值使其看起来不同,或者您可以使用转换器:

    class StyleConverter : DependencyObject, IValueConverter
    {
        public Style Style1 { get; set; }
    
        public Style Style2 { get; set; }
    
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool b = (bool)value;
            return b ? Style1 : Style2;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
    

    XAML:

    <Button x:Name="MyButton" Content="Button" Command="{Binding ButtonCommand}">
        <Button.Style>
            <Binding Path="SomeBooleanProperty">
                <Binding.Converter>
                    <local:StyleConverter Style1="{StaticResource Style1}" Style2="{StaticResource Style2}" />
                </Binding.Converter>
            </Binding>
        </Button.Style>
    </Button>
    

    【讨论】:

    • 我在使用转换器时遇到问题。您介意演示一下如何使用样式中的触发器来实现吗?
    • @fs_tigre:您不会在样式中使用它。正如我在回答中所展示的那样,您可以准确地使用它,即转换器返回一种或另一种风格。
    【解决方案3】:

    这就是我最终使用单一样式所做的事情。

     <Style x:Key="Style1" TargetType="{x:Type Button}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding SomeBooleanProperty}" Value="False">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type Button}">
                                    <Grid>
                                        <Image x:Name="image1" Source="Images/image.png" Stretch="None" />
                                        <Image x:Name="image2" Source="Images/image-hover.png" Stretch="None" Opacity="0" />
                                        <ContentPresenter />
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsMouseOver" Value="True">
                                            <Trigger.EnterActions>
                                                <StopStoryboard BeginStoryboardName="MouseLeaveStoryboard" />
                                                <BeginStoryboard Name="MouseOverStoryboard" Storyboard="{StaticResource MouseOverStoryboard}" />
                                            </Trigger.EnterActions>
    
                                            <Trigger.ExitActions>
                                                <StopStoryboard BeginStoryboardName="MouseOverStoryboard" />
                                                <BeginStoryboard Name="MouseLeaveStoryboard" Storyboard="{StaticResource MouseLeaveStoryboard}" />
                                            </Trigger.ExitActions>
    
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
    
                    <DataTrigger Binding="{Binding IsCSomeBooleanPropertyurrentPage}" Value="True">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type Button}">
                                    <Grid>
                                        <Image x:Name="image1" Source="Images/image2.png" Stretch="None" />
                                        <Image x:Name="image2" Source="Images/image-hover2.png" Stretch="None" Opacity="0" />
                                        <ContentPresenter />
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsMouseOver" Value="True">
    
                                            <Trigger.EnterActions>
                                                <StopStoryboard BeginStoryboardName="MouseLeaveStoryboard" />
                                                <BeginStoryboard Name="MouseOverStoryboard" Storyboard="{StaticResource MouseOverStoryboard}" />
                                            </Trigger.EnterActions>
    
                                            <Trigger.ExitActions>
                                                <StopStoryboard BeginStoryboardName="MouseOverStoryboard" />
                                                <BeginStoryboard Name="MouseLeaveStoryboard" Storyboard="{StaticResource MouseLeaveStoryboard}" />
                                            </Trigger.ExitActions>
    
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
    

    【讨论】:

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