C# - WPF从代码隐藏的DataTemplate中访问元素

时间:2016-06-06 08:57:38

标签: c# xml wpf storyboard datatemplate

我试图在WPF中创建一个纸牌游戏。 我的问题是我想在某个时间翻转一张卡片。 我在datatemplate中创建了两个故事板,每个翻转一个(后面和前面)。但是当我尝试从后面的代码中访问并启动它时,我得到了一个错误,因为它无法在datatemplate中访问包含新卡片图像的网格。 所以我的问题是,如何从后面的代码访问datatemplate中的网格,以使我的故事板运行?

这是我的代码:

XAML:

<Window x:Class="KartenQuartett.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:KartenQuartett"
    mc:Ignorable="d"
    ResizeMode="NoResize"
    Title="{Binding Title}" Height="510" Width="670" WindowStartupLocation="CenterScreen">
<Window.Resources>
    <DataTemplate x:Key="RotatingItemTemplate">
        <DataTemplate.Resources>
            <Storyboard x:Key="Storyboard1">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.LayoutTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="grid">
                    <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="-1">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                </DoubleAnimationUsingKeyFrames>
                <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.ZIndex)" Storyboard.TargetName="grid1">
                    <EasingInt32KeyFrame KeyTime="0" Value="0"/>
                    <EasingInt32KeyFrame KeyTime="0:0:0.5" Value="0"/>
                    <EasingInt32KeyFrame KeyTime="0:0:0.5" Value="1"/>
                </Int32AnimationUsingKeyFrames>
                <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.ZIndex)" Storyboard.TargetName="image">
                    <EasingInt32KeyFrame KeyTime="0" Value="1"/>
                    <EasingInt32KeyFrame KeyTime="0:0:0.5" Value="1"/>
                    <EasingInt32KeyFrame KeyTime="0:0:0.5" Value="0"/>
                </Int32AnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Key="Storyboard1_reversed">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.LayoutTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="grid">
                    <SplineDoubleKeyFrame KeyTime="0" Value="-1"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="1">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                </DoubleAnimationUsingKeyFrames>
                <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.ZIndex)" Storyboard.TargetName="grid1">
                    <EasingInt32KeyFrame KeyTime="0:0:0.5" Value="1"/>
                    <SplineInt32KeyFrame KeyTime="0:0:0.5" Value="0"/>
                    <SplineInt32KeyFrame KeyTime="0:0:1" Value="0"/>
                </Int32AnimationUsingKeyFrames>
                <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.ZIndex)" Storyboard.TargetName="image">
                    <SplineInt32KeyFrame KeyTime="0:0:0.5" Value="0"/>
                    <SplineInt32KeyFrame KeyTime="0:0:0.5" Value="1"/>
                    <SplineInt32KeyFrame KeyTime="0:0:1" Value="1"/>
                </Int32AnimationUsingKeyFrames>
            </Storyboard>
        </DataTemplate.Resources>
        <Grid x:Name="grid">
                <Grid.LayoutTransform>
                    <TransformGroup>
                        <ScaleTransform CenterX="0.5" CenterY="0.5"/>
                        <SkewTransform CenterX="0.5" CenterY="0.5"/>
                        <RotateTransform CenterX="0.5" CenterY="0.5"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Grid.LayoutTransform>
                <Grid x:Name="grid1">
                <Image x:Name="image1" Source="{Binding ImageFront}" Stretch="Fill" />
                                            <Grid.LayoutTransform>
                            <TransformGroup>
                                <ScaleTransform ScaleX="-1"/>
                                <SkewTransform/>
                                <RotateTransform/>
                                <TranslateTransform/>
                            </TransformGroup>
                            </Grid.LayoutTransform>
                                           </Grid>
                <Image x:Name="image" Source="{Binding Image}" Stretch="Fill" />
            <Button x:Name="Bdrehen" Content="Drehen" HorizontalAlignment="Left" Margin="119,407,0,0" VerticalAlignment="Top" Width="75" Click="Bdrehen_Click"/>
            </Grid>
            <DataTemplate.Triggers>
            <EventTrigger  RoutedEvent="Button.Click" SourceName="Bdrehen">
                <BeginStoryboard x:Name="Storyboard1_BeginStoryboard1" Storyboard="{StaticResource Storyboard1}"/>
            </EventTrigger>
            <EventTrigger RoutedEvent="UIElement.MouseLeftButtonDown" SourceName="grid1">
                <StopStoryboard BeginStoryboardName="Storyboard1_BeginStoryboard1"/>
                <BeginStoryboard x:Name="Storyboard1_reversed_BeginStoryboard" Storyboard="{StaticResource Storyboard1_reversed}"/>
            </EventTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</Window.Resources>

<Grid>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width=".5*"></ColumnDefinition>
        <ColumnDefinition Width=".5*"></ColumnDefinition>
    </Grid.ColumnDefinitions>

    <Grid Grid.Column="0" x:Name="gridOne">
        <Image x:Name="cardFront" Source="Bilder/card_front.png" Stretch="Fill">
        </Image>
        <StackPanel x:Name="stack1" Margin="25">

        </StackPanel>

    </Grid>

    <Grid Grid.Column="1" x:Name="gridTwo">

            <ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" >

            <ItemsControl ItemsSource="{Binding MyImages}" 
                          ItemsPanel="{DynamicResource ItemsPanelTemplate1}" 
                          ItemTemplate="{DynamicResource RotatingItemTemplate}">
            <ItemsControl.Resources>

                <ItemsPanelTemplate x:Key="ItemsPanelTemplate1">

                        <VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True"/>

                    </ItemsPanelTemplate>
            </ItemsControl.Resources>

        </ItemsControl>
    </ScrollViewer>

        <StackPanel x:Name="stack2" Margin="25">
        </StackPanel>

    </Grid>
</Grid>

所以&#34;网格&#34;和&#34; grid1&#34;是无法访问的元素。

对于测试我创建了一个按钮&#34; Bdrehen&#34;检查,如果我可以从按钮访问翻盖。这很完美,它也可以通过鼠标左键单击它。但不是代码。

下面是代码,我尝试从后面的代码启动代码:

DataTemplate dt = (DataTemplate)FindResource("RotatingItemTemplate");            
    Storyboard sb = dt.Resources["Storyboard1_reversed"] as Storyboard;
    BeginStoryboard(sb);

启动后我得到一个错误,即&#34; grid&#34;无法在&#34; KartenQuartett.MainWindow&#34;的名称空间中找到。 我可以在datatemplate中找到我的故事板,但不能找到我的网格。

有人有想法解决它吗?

1 个答案:

答案 0 :(得分:0)

以下是您的回答Calling Storyboard inside DataTemplate

但请记住,这样做并不是一个好主意。从您的代码中访问任何UI元素并不是一个好主意,因为它会在您的代码和UI之间产生紧密耦合。

我建议你改用MVVM,并绑定一个布尔值来运行你的故事板,如下所述:How to play Storyboard in ViewModel?