WPF - 它得是更容易比我做它(WPF — it's gotta be easier t

2019-07-31 12:39发布

我具有darndest时间搞清楚了这一点:说我有两个按钮和三个的TextBlocks。 我想无论是按钮,触发所有的TextBlocks一个简单的故事板。 目前,我试图定义一个包含故事板,然后触发来自任何按钮点击一个通用的文本块风格。 这是我来最接近的,但在启动应用程序崩溃...我是什么做的没有错在这里:

<Window.Resources>

<Style TargetType="TextBlock" >
    <Setter Property="Foreground" Value="Blue" />
    <Style.Resources>
        <Storyboard x:Key="TextBlockOpacity" Storyboard.TargetProperty="Opacity">
            <DoubleAnimation From="0" To="1" />
        </Storyboard>
    </Style.Resources>      
</Style>

<Window.Triggers>
    <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button">
        <BeginStoryboard Storyboard="{StaticResource TextBlockOpacity}"/>
    </EventTrigger>
</Window.Triggers>


<Grid x:Name="LayoutRoot">
    <Button x:Name="button" HorizontalAlignment="Left" Margin="51,54,0,0" VerticalAlignment="Top" Width="96" Height="45" Content="Button"/>

    <TextBlock x:Name="textBlock1" Margin="228,54,172,0" VerticalAlignment="Top" Height="45" FontSize="26.667" Text="TextBlock" TextWrapping="Wrap" />
    <TextBlock x:Name="textBlock2" Margin="228,103,172,0" VerticalAlignment="Top" Height="45" FontSize="26.667" Text="Hello" TextWrapping="Wrap"/>
</Grid>

Answer 1:

基于kek444的XAML的唯一的解决办法,我提出不依赖于按钮的DataContext的,可以有多个触发器略微改进版。

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="WpfApplication1.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640" Height="480">
    <Window.Resources>
        <UIElement x:Key="OpacityCounter" Opacity="0"/>
        <Style TargetType="TextBlock">
            <Setter Property="Opacity" Value="{Binding Source={StaticResource OpacityCounter}, Path=Opacity}" />
        </Style>
        <Storyboard x:Key="OnClick1">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.Target="{StaticResource OpacityCounter}" Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button1">
            <BeginStoryboard Storyboard="{StaticResource OnClick1}"/>
        </EventTrigger>
        <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button2">
            <BeginStoryboard Storyboard="{StaticResource OnClick1}"/>
        </EventTrigger>
    </Window.Triggers>

    <Grid x:Name="LayoutRoot">
        <StackPanel>
            <StackPanel Orientation="Horizontal">
                <Button x:Name="button1" Width="131" Height="37" Content="Button 1" Margin="0,0,0,22"/>
                <Button x:Name="button2" Width="131" Height="37" Content="Button 2" Margin="0,0,0,22"/>
            </StackPanel>
            <TextBlock x:Name="textBlock" Height="27" Text="TextBlock 1" TextWrapping="Wrap" />
            <TextBlock x:Name="textBlock1" Height="27" Text="TextBlock 2" TextWrapping="Wrap" />
            <TextBlock x:Name="textBlock2" Height="27" Text="TextBlock 3" TextWrapping="Wrap" />
            <TextBlock x:Name="textBlock3" Height="27" Text="TextBlock 4" TextWrapping="Wrap" />
        </StackPanel>
    </Grid>
</Window>

要使用列表框作为一种触发机制(前提是你有一个名为“ListBox1的”在某处列表框,添加以下Window.Triggers:

<EventTrigger RoutedEvent="Selector.SelectionChanged" SourceName="listbox1">
    <BeginStoryboard Storyboard="{StaticResource OnClick1}"/>
</EventTrigger>

或触发关闭特定ListBoxItem的,你需要(其中物品1被命名ListBoxItem的):

<EventTrigger RoutedEvent="ListBoxItem.Selected" SourceName="item1">
    <BeginStoryboard Storyboard="{StaticResource OnClick1}"/>
</EventTrigger>


Answer 2:

如果“奉献”按钮,改变的不透明度,你可以利用它DataContext和动画它。 然后,只需绑定你的元素的OpacityDataContext

(我也重构XAML中位)

<Window x:Class="SomeNamespace.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>        
        <Storyboard x:Key="TextBlockOpacity" Storyboard.TargetName="button1" Storyboard.TargetProperty="DataContext" >
            <DoubleAnimation From="0.1" To="1"/>
        </Storyboard>        
        <Style TargetType="TextBlock" >
            <Setter Property="Foreground" Value="Blue" />
            <Setter Property="Background" Value="LightGray" />
            <Setter Property="FontSize" Value="26.667" />
            <Setter Property="TextWrapping" Value="Wrap" />
            <Setter Property="Height" Value="45" />            
            <Setter Property="Opacity" Value="{Binding ElementName=button1, Path=DataContext}"/>
        </Style>
    </Window.Resources>

    <Window.Triggers>
        <EventTrigger RoutedEvent="ButtonBase.Click">
            <BeginStoryboard Storyboard="{StaticResource TextBlockOpacity}" >
            </BeginStoryboard>
        </EventTrigger>

        <EventTrigger RoutedEvent="ListBox.SelectionChanged">
            <BeginStoryboard Storyboard="{StaticResource TextBlockOpacity}" >
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>

    <Grid x:Name="LayoutRoot">
        <Button x:Name="button1" HorizontalAlignment="Left" Margin="51,54,0,0" VerticalAlignment="Top" Width="96" Height="45" Content="Button">
            <Button.DataContext>
                <System:Double>0</System:Double>
            </Button.DataContext>
        </Button>

        <Button x:Name="button2" HorizontalAlignment="Right" Margin="0,54,29,0" VerticalAlignment="Top" Width="96" Height="45" Content="Button"/>

        <ListBox x:Name="listBox1" Height="50" VerticalAlignment="Top">
            <ListBox.Items>
                <System:String>Text1</System:String>
                <System:String>Text2</System:String>
            </ListBox.Items>
        </ListBox>

        <TextBlock x:Name="textBlock1" Margin="51,114,61,0" Text="TextBlock" Height="45" VerticalAlignment="Top" Width="166" />
        <TextBlock x:Name="textBlock2" Margin="51,0,74,42" Text="Hello" Height="45" Width="153" VerticalAlignment="Bottom" />
    </Grid>
</Window>

还要注意一两件事-这是,如果你希望尽量减少你的代码使用使这一切在XAML中发生的办法。 你的做法将anmate的Opacity整个窗口。 这就是为什么在上面的代码中,绑定的TextBlocks到该按钮的DataContext ,这本身就是动画。

这当然是可行的不绑定到一个共同的价值(在DataContext)的,但你需要重复X动画(因为你需要设置X TargetNames)。 上面这种方法更易于扩展和维护。

编辑

增加了一个按钮和品种的列表框:)



Answer 3:

在您的样品,要定义样式的资源里面的故事板,但你正在试图访问它作为一个窗口资源。 尝试将故事板申报转移到Window.Resources,然后引用故事板的样式。

我不知道对不对关闭,如果它会做你想要什么,但我会从那里开始。



文章来源: WPF — it's gotta be easier than I'm making it