【问题标题】:Controlling a UserControl's Storyboard from the parent Window in WPF using only XAML仅使用 XAML 从 WPF 中的父窗口控制 UserControl 的情节提要
【发布时间】:2010-10-01 03:04:22
【问题描述】:

我创建了一个非常简单的测试应用程序来尝试解决同事向我描述的这个问题。他能够在 C# 中触发它,但我相信他需要更通用的解决方案,并希望它严格在 XAML 中完成。问题是:如何触发 UserControl 内的 Storyboard 以响应包含窗口中的控件上的事件(父级不必是 Window,它可以是 Page 或另一个 UserControl.. .为了简单起见,我使用一个窗口)。所以,我最好的例子是你有一个带有按钮的窗口和一个用户控件的实例。您希望 Button 的 Click 事件触发 UserControl 内的 Storyboard 开始。

在 UserControl 本身内部,Storyboard 被声明为具有 MyStoryboard 键的 Resource。我创建了一个带有 EventTrigger 的 Button,以表明我可以通过使用 Binding 表达式引用它来触发 Storyboard。这是我的 UserControl 的完整 XAML:

<UserControl x:Class="UserControlStoryboard.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<UserControl.Resources>
    <Storyboard x:Key="MyStoryboard">
        <ColorAnimation Storyboard.TargetName="grid" Storyboard.TargetProperty="(Grid.Background).Color" From="CadetBlue" To="White" Duration="0:0:2" />
    </Storyboard>
</UserControl.Resources>
<Grid Background="CadetBlue" x:Name="grid">
    <Button Content="Press Me" Height="50">
        <Button.Triggers>
            <EventTrigger RoutedEvent="Button.Click">
                <BeginStoryboard>
                    <BeginStoryboard.Storyboard>
                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" Path="Resources[MyStoryboard]" />
                    </BeginStoryboard.Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Button.Triggers>
    </Button>            
</Grid>

我希望,因为我能够通过使用 Binding 表达式引用 Storyboard 来告诉 Storyboard,所以我应该能够从包含此 UserControl 作为子元素的 Window 中执行完全相同的操作。但我似乎无法弄清楚如何在父窗口中获取对情节提要的引用。这仅在 XAML 中是不可能完成的吗?

我的测试项目中的父窗口只有一个按钮和这个 UserControl 的一个实例。如果可能的话,哪个元素可以让我添加一个 EventTrigger,其中事件源是 Button,并且触发动作告诉 UserControl 的情节提要开始?

谢谢。

【问题讨论】:

  • 我的情况很相似,你有没有找到解决办法?
  • 不幸的是,没有。这个问题是两年前提出的。从那以后,我用模板绑定做了一些非常棘手的事情,以在父控件和子控件之间来回通信。现在有了这种经验,我实际上更喜欢更直接的 C# 方法。我看到的用 xaml、绑定、视图模型等完成的花哨技巧越多,我就越畏缩……可能会成为一场巨大的调试噩梦。

标签: c# .net wpf xaml


【解决方案1】:

我认为在 UserControl 中响应外部事件的想法不是很安全。在 UserControl 中,您只想对控件中产生的事件做出反应。

你能扭转局面并做以下事情吗?

  • 将需要动画的UC属性暴露为依赖属性(本例为背景)
  • 在父窗口上同时创建 EventTrigger 和 Storyboard

【讨论】:

  • “我认为在 UserControl 中响应外部事件的想法不是很安全”。为什么?这个概念可以追溯到响应宿主容器中的环境属性的 ActiveX 控件或 ActiveX 文档。当然,现在我们谈论的是 WPF,但我认为这个概念是一样的
【解决方案2】:

您可以使用 StaticResource 访问情节提要。您只需将资源分配给 BeginStroyboard 上的 Storyboard。

<BeginStoryboard Storyboard="{StaticResource MyStoryboard}">
</BeginStoryboard>

我将代码更改为以下内容,当您按下按钮时,它将为您启动故事板。希望这会有所帮助。

    <UserControl.Resources>
    <Storyboard x:Key="MyStoryboard">
        <ColorAnimation Storyboard.TargetName="grid" Storyboard.TargetProperty="(Grid.Background).Color" From="CadetBlue" To="White" Duration="0:0:2" />
    </Storyboard>
</UserControl.Resources>
<Grid Background="CadetBlue" x:Name="grid">
    <Button Content="Press Me" Height="50">
        <Button.Triggers>
            <EventTrigger RoutedEvent="Button.Click">
                <BeginStoryboard Storyboard="{StaticResource MyStoryboard}">
                </BeginStoryboard>
            </EventTrigger>
        </Button.Triggers>
    </Button>
</Grid>

【讨论】:

    【解决方案3】:

    使用纯 Xaml 可能没有很好的方法。

    你可以:

    • 在您的 UserControl 上创建一个接受 Button 的依赖属性,然后您可以绑定到它。
    • 制作某种疯狂的转换器,它会遍历您的视觉树,寻找特定的东西。

    两者都需要一些 C#,所以我不知道以上是否是您正在寻找的。​​p>

    【讨论】:

      猜你喜欢
      • 2011-07-03
      • 1970-01-01
      • 1970-01-01
      • 2015-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      相关资源
      最近更新 更多