代码隐藏中的System.Windows.Interactivity.EventTrigger适用于某些控件,但不适用于其他控件

时间:2011-12-30 18:38:11

标签: c# silverlight windows-phone-7 expression-blend

我有一个应用程序,我在运行时添加控件,并希望附加EventTrigger(s) PlaySoundAction。在XAML中这很容易,但是需要动态生成控件并添加这些触发器,这会变得有点困难。

我在一个previous question中问了一下,并且能够在那里找到一部分并且通过最近的测试,我已经得出了我能做些什么来解决它的结论,但是希望可能有一些我遗漏的东西。我可以让EventTrigger在Button控件上工作,但不能在RegularPolygon上工作,我无法轻松地在RegularPolygon中嵌入一个按钮来实现我想要的结果,因为它不是一个ContentControl。

这就是我目前有这种方法将新的RegularPolygons添加到容器(Canvas):

public RegularPolygon AddShape(Panel container)
{
    RegularPolygon shape = new RegularPolygon();

    // ShapeColors is a List<SolidColorBrush> that has been prepopulated
    // _random is a Random() from .NET
    shape.Fill = ShapeColors[_random.Next(0, ColorCount - 1)];
    shape.Stretch = Stretch.Fill;
    shape.PointCount = _random.Next(3, 6);
    shape.UseLayoutRounding = false;
    shape.Stroke = new SolidColorBrush(Colors.Black);
    shape.Width = _random.Next(50, 150);
    shape.Height = _random.Next(50, 150);
    // UI_Tap is an arbitrary function for handling the Tap event
    shape.Tap += UI_Tap;

    System.Windows.Interactivity.EventTrigger trigger = new System.Windows.Interactivity.EventTrigger("Tap");
    PlaySoundAction correct = new PlaySoundAction();
    correct.Source = new Uri("/Sounds/Correct.mp3", UriKind.RelativeOrAbsolute);
    correct.Volume = 1;

    trigger.Actions.Add(correct);

    //Button b = new Button();
    //b.Content = "This is button B";
    //System.Windows.Interactivity.Interaction.GetTriggers(b).Add(trigger);
    //container.Children.Add(b);

    // Comment this line out when uncommenting Button b block because Triggers 
    // can only be associated with one element
    System.Windows.Interactivity.Interaction.GetTriggers(shape).Add(trigger);

    Canvas.SetLeft(shape, _random.Next((int)(shape.Width / 2), (int)(container.Width - (shape.Width / 2))));
    Canvas.SetTop(shape, _random.Next((int)(shape.Height / 2), (int)(container.Height - (shape.Height / 2))));
    container.Children.Add(shape);

    return shape;
}

我可以看到我的所有RegularPolygons出现在屏幕上。我已经测试过,确保声音文件的路径通过让其他测试控件尝试在列出的位置引用它来工作。没有运气使用PlaySoundAction的EventTrigger工作。如果我取消注释按钮b周围的线条,我可以看到添加的按钮并点按它以听到声音播放。

我可以使用RegularPolygon在XAML中使用PlaySoundAction EventTrigger,如下所示:

<es:RegularPolygon x:Name="haxx" Fill="#FFF4F4F5" Height="100" InnerRadius="1" Canvas.Left="125" PointCount="5" Stretch="Fill" Stroke="Black" Canvas.Top="187" UseLayoutRounding="False" Width="100">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Tap">
            <eim:PlaySoundAction Source="/Sounds/Correct.mp3"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</es:RegularPolygon>

我即将推出的解决方案是创建一个自定义控件,让我使用RegularPolygon的形状和Button的功能,因为我可以从代码隐藏中使用它。有什么我想念的东西阻止我使用这个EventTrigger吗?

1 个答案:

答案 0 :(得分:0)

这是一个问题中没有足够信息的案例。 UI_Tap(...)方法有一些目标:

  • 点击RegularPolygon时播放声音
  • 确定是否需要将更多对象绘制到屏幕上(以避免物品无法触摸)
  • 从父容器中删除Tap'd RegularPolygon

从父容器中删除对象的原因是没有立即发现我的对象将被阻止执行与之关联的EventTrigger。这也是为什么将RegularPolygon硬编码到MainPage.xaml以及上面的Button上的原因是因为我从未试图在Tap事件处理程序中删除它们。

我有一些建议将PlaySoundAction的EventTrigger绑定到ManipulationStartedEvent,因为它发生在Tap事件之前,这会起作用,但是我会在更新期间使用XNA库来播放SoundEffect的更复杂的路径环。它涉及创建一个IApplicationLifetimeService并将声音排队以在FrameDispatchTimer_Tick事件中播放,如下所示:

FrameworkDispatcher.Update has not been called and what to do about it

相关问题