【问题标题】:How do you add an Event Trigger to a data template for a business object?如何将事件触发器添加到业务对象的数据模板?
【发布时间】:2009-09-14 17:39:23
【问题描述】:

我有一个名为 BlinkingLight 的自定义类。 我还有一个静态 ObservableCollection BlinkingLightCollection。 在 UI 中,我有一个绑定到 BlinkingLightCollection 的 ListBox。

在我的 ListBox 中,我想基本上将每个 BlinkingLight 对象显示为一个自定义控件,该控件看起来像一个带有 LED 灯的盒子,它有一个动画,使 LED 看起来就像它只是闪烁了一秒钟然后恢复正常。

我的 BlinkingLight 类具有引发名为“Flash”的事件的第三方“LED”对象。

我正在寻找想法或解决方案以使其发挥作用!

我的失败尝试:

我创建了一个自定义控件 (BlinkingLightControl),当 BlinkingLight 是我的自定义控件的 DataContext 时,它可以绑定到我的 BlinkingLight 类的数据。

我为我的 ListBox 创建了一个 DataTemplate:

<Window.Resources>
  <DataTemplate x:Key="blinkingLightItemTemplate" >
    <local:BlinkingLightControl />
  </DataTemplate>
</Window.Resources>

<ListBox ItemsSource={Binding Source={x:Static local:Data.BlinkingLightCollection}}
         ItemTemplate="{StaticResource blinkingLightItemTemplate}" />

注意:我可以将自定义控件的 xaml 放入数据模板中,而不是使用完全不同的控件,如果这样可以让事情变得更容易。

现在我想在我的 BlinkingLightControl(或 DataTemplate)中有一个 EventTrigger,它的 RoutedEvent 是 LED.Flash 事件。不幸的是,我似乎无法弄清楚这部分。我试图在我的 BlinkingLight 类中创建一个 RoutedEvent ,并在我处理 LED.Flash 事件时引发它。但是我的课程不是 UIElement 或 ContentElement,根据 MSDN:MSND Link

“路由事件所有者可以是任何类,但路由事件必须由 UIElement 或 ContentElement 派生类引发和处理才能有用。有关自定义事件的更多信息,请参阅如何:创建自定义路由事件。”

任何帮助将不胜感激!! 谢谢, 斯科特

【问题讨论】:

    标签: c# wpf events datatemplate eventtrigger


    【解决方案1】:

    在这种情况下,最好的方法是使用 WPF 命令并创建一个“BlinkTheLights”RoutedCommand - 您的 BlinkingLightControl 将处理 BlinkTheLights 命令,并通过启动一个让灯闪烁的 StoryBoard 来响应。

    【讨论】:

    • 感谢您的回复!我还没有探索过 WPF 中命令的使用,但我会试一试,让大家知道它是如何工作的!
    【解决方案2】:

    我想出了一个效果很好的解决方案:

    由于我的 DataTemplate 仅包含一个自定义 UserControl(它绑定到 DataContext 以从业务对象获取其数据)...我将自定义 RoutedEvent 放在 UserControl 中。然后在我的 UserControl 的加载事件中,我将 DataContext 转换为我的业务对象,以访问具有该事件的业务对象的属性并将其连接到事件处理程序。 (在我的示例中,我将 DataContext 转换为 BlinkingLight 对象,然后我可以访问其 Led 属性的 Flash 事件并将其连接到自定义事件处理程序)。 注意:LED 对象必须是一个属性,而不仅仅是 BlinkingLight 对象中的一个字段才能工作。

    然后事件处理程序可以引发 UserControl 的自定义路由事件 (FlashGreenEvent)。下面是现在补充 OP 中代码的后端代码(我已经删除了任何其他不相关的代码)。

    public partial class BlinkingLightControl : UserControl
    {
        public static readonly RoutedEvent FlashGreenEvent = EventManager.RegisterRoutedEvent("FlashGreen", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(BlinkingLightControl));
        public event RoutedEventHandler FlashGreen
        {
            add { AddHandler(FlashGreenEvent, value); }
            remove { RemoveHandler(FlashGreenEvent, value); }
        }
    
        private void BlinkingLightControl_Loaded(object sender, RoutedEventArgs e)
        {
            BlinkingLight blinkingLight = (BlinkingLight)this.DataContext;
    
            blinkingLight.Led.Flash += LED_Flash;
        }
    
        protected delegate void LED_FlashCallback(ThirdParty.LED sender);
        public void LED_Flash(ThirdParty.LED sender)
        {
            if (this.Dispatcher.CheckAccess())
            {
                // Raise the Flash Green Event;
                RaiseEvent(new RoutedEventArgs(BlinkingLightControl.FlashGreenEvent));
            }
            else
                this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new LED_FlashCallback(LED_Flash), sender);
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果您要制作自定义控件,则始终可以在控件模板之外设置触发器。

      类似:

        <Style TargetType="{x:Type local:MyControl}">
      
        <!-- fade in the control with an animation -->
        <Style.Triggers>
          <EventTrigger RoutedEvent="Control.Loaded">
            <BeginStoryboard>
              <Storyboard>
               <DoubleAnimation To="1" Duration="0:0:1" Storyboard.TargetProperty="Opacity"/>
              </Storyboard>
            </BeginStoryboard>
          </EventTrigger>
        </Style.Triggers>
      
        <!-- Make sure the opacity starts at 0 -->
        <Setter Property="Opacity" Value="0"/>
        <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate TargetType="{x:Type local:MyControl}">
               </ControlTemplate>
            </Setter.Value>
        </Setter>
      </Style>
      

      【讨论】:

        猜你喜欢
        • 2013-12-25
        • 2010-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多