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

C# - WPF Access elements in a DataTemplate from code behind

我尝试在 WPF 中创建纸牌游戏。 我的问题是我想在特定时间翻转卡片。 我在数据模板中创建了两个情节提要,每次翻转一个(前后)。但是当我尝试从后面的代码访问并启动它时出现错误,因为它无法访问数据模板内包含新卡片图像的网格。 所以我的问题是,如何从后面的代码访问数据模板内的网格,以获取故事板 运行?

这是我的代码:

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>

所以"grid"和"grid1"是不能访问的元素

为了测试,我创建了一个按钮 "Bdrehen" 来检查我是否可以通过按钮访问翻盖。这很完美,它也可以通过用鼠标左键单击它来工作。但不是通过代码。

这是代码,我尝试从后面的代码开始:

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

启动后出现错误,无法在 "KartenQuartett.MainWindow" 的命名空间中找到 "grid"。 我可以在数据模板中找到我的故事板,但找不到我的网格。

有人有解决办法吗?

这是你的答案Calling Storyboard inside DataTemplate

但请记住,这样做并不是一个好主意。从后面的代码访问任何 UI 元素不是一个好主意,因为它会在您的代码和 UI.

之间创建紧密耦合

我建议你使用 MVVM instead, and to bind a boolean to run your storyboard as explained here: How to play Storyboard in ViewModel?