簡體   English   中英

不能在 Style Setter 上設置 TargetName 屬性,那么它是如何設置的呢?

[英]TargetName property cannot be set on a Style Setter, so how is it set?

過去一周我一直在探索 WPF,所以它對我來說仍然很陌生。 我正在做的一件事是簡單的動畫。 在這種情況下,一個彈跳的笑臉。

我的攻擊計划是:

  1. 做個笑臉。 我已經這樣做了。
  2. 在一個簡單的對象上制定彈跳動畫。 我已經這樣做了。
  3. 抽象該動畫,以便它可以在多個地方使用(笑臉的元素)。 我被困在這里。
  4. 將抽象的動畫風格應用於笑臉的所有元素。

在第 2 步之后,我有以下工作 XAML:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="Test Window" Height="350" Width="620">
    <Grid>
        <Canvas Margin="0,180,0,0">
            <Ellipse Canvas.Left="10" Canvas.Top="10" Width="100" Height="100" Stroke="Blue" StrokeThickness="4" Fill="Aqua" />
            <Ellipse Canvas.Left="30" Canvas.Top="12" Width="60" Height="30">
                <Ellipse.Fill>
                    <LinearGradientBrush StartPoint="0.45,0" EndPoint="0.5, 0.9">
                        <GradientStop Offset="0.2" Color="DarkMagenta" />
                        <GradientStop Offset="0.7" Color="Transparent" />
                    </LinearGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
            <Ellipse Canvas.Left="33" Canvas.Top="35" Width="20" Height="20" Stroke="Blue" StrokeThickness="3" Fill="White" />
            <Ellipse Canvas.Left="40" Canvas.Top="43" Width="6" Height="5" Fill="Black" />
            <Ellipse Canvas.Left="68" Canvas.Top="35" Width="20" Height="20" Stroke="Blue" StrokeThickness="3" Fill="White" />
            <Ellipse Canvas.Left="75" Canvas.Top="43" Width="6" Height="5" Fill="Black" />
            <Path Name="mouth" Stroke="Blue" StrokeThickness="4" Data="M 35,75 Q 55,90 80,75 " />
        </Canvas>
        <Grid Margin="100,5,0,0" Width="75" Height="300">
            <Canvas>
                <Ellipse Height="40" Width="40" x:Name="theBall" Canvas.Left="16">
                    <Ellipse.Fill>
                        <RadialGradientBrush GradientOrigin="0.75,0.25">
                            <GradientStop Color="Yellow" Offset="0.0" />
                            <GradientStop Color="Red" Offset="1.0" />
                        </RadialGradientBrush>
                    </Ellipse.Fill>
                    <Ellipse.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform x:Name="aniSquash"/>
                            <TranslateTransform x:Name="aniBounce"/>
                        </TransformGroup>
                    </Ellipse.RenderTransform>
                    <Ellipse.Triggers>
                        <EventTrigger RoutedEvent="Loaded">
                            <BeginStoryboard>
                                <Storyboard SpeedRatio="2.0">
                                    <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniBounce" Storyboard.TargetProperty="Y" RepeatBehavior="Forever">
                                        <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
                                        <SplineDoubleKeyFrame Value="260" KeyTime="0:0:2.2" KeySpline="0, 0, 0.5, 0"/>
                                        <LinearDoubleKeyFrame Value="260" KeyTime="0:0:2.25"/>
                                        <SplineDoubleKeyFrame Value="120" KeyTime="0:0:4.5" KeySpline="0, 0, 0, 0.5"/>
                                    </DoubleAnimationUsingKeyFrames>
                                    <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleX" RepeatBehavior="Forever">
                                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                                        <LinearDoubleKeyFrame Value="1.3" KeyTime="0:0:2.25"/>
                                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                                    </DoubleAnimationUsingKeyFrames>
                                    <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleY" RepeatBehavior="Forever">
                                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                                        <LinearDoubleKeyFrame Value="0.7" KeyTime="0:0:2.25"/>
                                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                                    </DoubleAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </Ellipse.Triggers>
                </Ellipse>
                <Rectangle Height="5" Canvas.Left="10" Canvas.Top="285" Width="55" Fill="Black"/>
            </Canvas>
        </Grid>
    </Grid>
</Window>

在更改上述內容時,第 3 步的 XAML 工作引入了一個我不太了解的錯誤。 這是無效的更改后的 XAML:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="Test Window" Height="350" Width="620">
    <Window.Resources>
        <TransformGroup x:Key="aniBounceAndSquash">
            <ScaleTransform x:Name="aniSquash"/>
            <TranslateTransform x:Name="aniBounce"/>
        </TransformGroup>
        <Style x:Key="styleBounceAndSquash" TargetType="FrameworkElement">
            <Setter Property="RenderTransform" Value="{StaticResource aniBounceAndSquash}" />
            <Style.Triggers>
                <EventTrigger RoutedEvent="Loaded">
                    <BeginStoryboard>
                        <Storyboard SpeedRatio="2.0">
                            <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniBounce" Storyboard.TargetProperty="Y" RepeatBehavior="Forever">
                                <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
                                <SplineDoubleKeyFrame Value="260" KeyTime="0:0:2.2" KeySpline="0, 0, 0.5, 0"/>
                                <LinearDoubleKeyFrame Value="260" KeyTime="0:0:2.25"/>
                                <SplineDoubleKeyFrame Value="120" KeyTime="0:0:4.5" KeySpline="0, 0, 0, 0.5"/>
                            </DoubleAnimationUsingKeyFrames>
                            <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleX" RepeatBehavior="Forever">
                                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                                <LinearDoubleKeyFrame Value="1.3" KeyTime="0:0:2.25"/>
                                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                            </DoubleAnimationUsingKeyFrames>
                            <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleY" RepeatBehavior="Forever">
                                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                                <LinearDoubleKeyFrame Value="0.7" KeyTime="0:0:2.25"/>
                                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <Canvas Margin="0,180,0,0">
            <Ellipse Canvas.Left="10" Canvas.Top="10" Width="100" Height="100" Stroke="Blue" StrokeThickness="4" Fill="Aqua" />
            <Ellipse Canvas.Left="30" Canvas.Top="12" Width="60" Height="30">
                <Ellipse.Fill>
                    <LinearGradientBrush StartPoint="0.45,0" EndPoint="0.5, 0.9">
                        <GradientStop Offset="0.2" Color="DarkMagenta" />
                        <GradientStop Offset="0.7" Color="Transparent" />
                    </LinearGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
            <Ellipse Canvas.Left="33" Canvas.Top="35" Width="20" Height="20" Stroke="Blue" StrokeThickness="3" Fill="White" />
            <Ellipse Canvas.Left="40" Canvas.Top="43" Width="6" Height="5" Fill="Black" />
            <Ellipse Canvas.Left="68" Canvas.Top="35" Width="20" Height="20" Stroke="Blue" StrokeThickness="3" Fill="White" />
            <Ellipse Canvas.Left="75" Canvas.Top="43" Width="6" Height="5" Fill="Black" />
            <Path Name="mouth" Stroke="Blue" StrokeThickness="4" Data="M 35,75 Q 55,90 80,75 " />
        </Canvas>
        <Grid Margin="100,5,0,0" Width="75" Height="300">
            <Canvas>
                <Ellipse Height="40" Width="40" x:Name="theBall" Canvas.Left="16" Style="{StaticResource styleBounceAndSquash}">
                    <Ellipse.Fill>
                        <RadialGradientBrush GradientOrigin="0.75,0.25">
                            <GradientStop Color="Yellow" Offset="0.0" />
                            <GradientStop Color="Red" Offset="1.0" />
                        </RadialGradientBrush>
                    </Ellipse.Fill>
                </Ellipse>
                <Rectangle Height="5" Canvas.Left="10" Canvas.Top="285" Width="55" Fill="Black"/>
            </Canvas>
        </Grid>
    </Grid>
</Window>

錯誤“無法在樣式設置器上設置 TargetName 屬性。第 20 行位置 79。”

如果我不能在樣式中設置它,我該如何設置?

事實證明,您不能在Style.Setter設置Storyboard.TargetName ,因為它是一種樣式並且是抽象的。 因此,不允許通過名稱進行引用,因為“沒有勺子”。 所以我放棄了Storyboard.TargetName並尋找另一種方式。

我確實發現在Storyboard.TargetProperty你可以使用對象結構,有點像遍歷 DOM,來引用你想要的對象。 通過這種方式,您可以繞過Storyboard.TargetName的需要。 由於我使用的是TransformGroup並且 MS 文檔不是最友好的文檔,因此按結構引用對象需要更長的時間。 最后,我得到了它,它適用於其他有同樣問題的人。

<Style x:Key="buttonSmiley" TargetType="{x:Type Button}">
    <Style.Resources>
        <Storyboard x:Key="OnVisibleStoryboard">
            <DoubleAnimationUsingKeyFrames Duration="0:0:2.75" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)" >
                <LinearDoubleKeyFrame Value="75" KeyTime="0:0:0"/>
                <SplineDoubleKeyFrame Value="25" KeyTime="0:0:0.75" KeySpline="0, 0, 0.5, 0"/>
                <LinearDoubleKeyFrame Value="-25" KeyTime="0:0:1.2"/>
                <SplineDoubleKeyFrame Value="200" KeyTime="0:0:2.25" KeySpline="0, 0, 0, 0.5"/>
                <LinearDoubleKeyFrame Value="175" KeyTime="0:0:2.4" />
                <SplineDoubleKeyFrame Value="150" KeyTime="0:0:2.75" KeySpline="0, 0, 0, 0.5"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Duration="0:0:5.5" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(ScaleTransform.ScaleX)" >
                <LinearDoubleKeyFrame Value="0.01" KeyTime="0:0:0"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:1.25"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.05"/>
                <LinearDoubleKeyFrame Value="1.15" KeyTime="0:0:2.15"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.4"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.75"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Duration="0:0:5.5" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(ScaleTransform.ScaleY)" >
                <LinearDoubleKeyFrame Value="0.01" KeyTime="0:0:0"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:1.25"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.05"/>
                <LinearDoubleKeyFrame Value="0.75" KeyTime="0:0:2.2"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.4"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.75"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Style.Resources>
    <Style.Triggers>
        <Trigger Property="Visibility" Value="Visible">
            <Trigger.EnterActions>
                <RemoveStoryboard BeginStoryboardName="OnLoadStoryboard_BeginStoryboard"/>
                <BeginStoryboard x:Name="OnVisibleStoryboard_BeginStoryboard" Storyboard="{StaticResource OnVisibleStoryboard}"/>
            </Trigger.EnterActions>
        </Trigger>
        <EventTrigger RoutedEvent="Button.Loaded">
            <RemoveStoryboard BeginStoryboardName="OnVisibleStoryboard_BeginStoryboard"/>
            <BeginStoryboard x:Name="OnLoadStoryboard_BeginStoryboard" Storyboard="{StaticResource OnVisibleStoryboard}"/>
        </EventTrigger>
    </Style.Triggers>
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Canvas Margin="-35,-35,0,0">
                    <Ellipse Canvas.Left="10" Canvas.Top="10" Width="50" Height="50" Stroke="Blue" StrokeThickness="2" Fill="#FFD8CF15" />
                    <Ellipse Canvas.Left="18" Canvas.Top="12" Width="33" Height="15">
                        <Ellipse.Fill>
                            <LinearGradientBrush StartPoint="0.45,0" EndPoint="0.5, 0.9">
                                <GradientStop Offset="0.2" Color="DarkMagenta" />
                                <GradientStop Offset="0.7" Color="Transparent" />
                            </LinearGradientBrush>
                        </Ellipse.Fill>
                    </Ellipse>
                    <Ellipse Canvas.Left="17" Canvas.Top="25" Width="10" Height="10" Stroke="Blue" StrokeThickness="2" Fill="White" />
                    <Ellipse Canvas.Left="20" Canvas.Top="28" Width="3" Height="3" Fill="Black" />
                    <Ellipse Canvas.Left="34" Canvas.Top="25" Width="10" Height="10" Stroke="Blue" StrokeThickness="2" Fill="White" />
                    <Ellipse Canvas.Left="37" Canvas.Top="28" Width="3" Height="3" Fill="Black" />
                    <Path Name="mouth" Stroke="Blue" StrokeThickness="2" Data="M 20,43 Q 27,53 40,44" />
                </Canvas>
            </DataTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="RenderTransform">
        <Setter.Value>
            <TransformGroup>
                <TranslateTransform />
                <ScaleTransform />
            </TransformGroup>
        </Setter.Value>
    </Setter>
</Style>

當然,如果Button.Triggers允許正常觸發器而不是集合中的 JUST 事件觸發器,我會完全放棄這種樣式,謝謝 MS 讓生活變得痛苦,呃,我的意思是有趣。 因為我需要兩者,所以我必須解決這個問題。

我遇到這個問題是因為我正在構建一個自定義資源(一個按鈕)。

這是我的問題,及其解決方案:

<Style x:Key="MyButton" TargetType="{x:Type Button}">
    ...
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                ...
                <ControlTemplate.Triggers>
                    ==> should have put triggers here <==
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        ==> not here <==
    </Style.Triggers>
</Style>

這是應用於Button動畫示例。 它可能不是您正在尋找的答案,因為它沒有可重用的資源。 我剛剛將TransformGroupTriggerStoryboard移到了控件中。 我再看看...

<Button Style="{StaticResource styleBounceAndSquash}">
    <Button.RenderTransform>
        <TransformGroup>
            <ScaleTransform x:Name="aniSquash"/>
            <TranslateTransform x:Name="aniBounce"/>
        </TransformGroup>
    </Button.RenderTransform>
    <Button.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <BeginStoryboard>
                <Storyboard SpeedRatio="2.0">
                    <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniBounce" Storyboard.TargetProperty="Y" RepeatBehavior="Forever">
                        <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
                        <SplineDoubleKeyFrame Value="260" KeyTime="0:0:2.2" KeySpline="0, 0, 0.5, 0"/>
                        <LinearDoubleKeyFrame Value="260" KeyTime="0:0:2.25"/>
                        <SplineDoubleKeyFrame Value="120" KeyTime="0:0:4.5" KeySpline="0, 0, 0, 0.5"/>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleX" RepeatBehavior="Forever">
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                        <LinearDoubleKeyFrame Value="1.3" KeyTime="0:0:2.25"/>
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleY" RepeatBehavior="Forever">
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                        <LinearDoubleKeyFrame Value="0.7" KeyTime="0:0:2.25"/>
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM