كيف يمكنك إضافة مشغل حدث إلى قالب بيانات لكائن أعمال؟

StackOverflow https://stackoverflow.com/questions/1422943

سؤال

لدي فئة مخصصة تسمى BlinkingLight.لدي أيضًا ObservableCollection ثابت BlinkingLightCollection.في واجهة المستخدم، لدي ListBox مرتبط بـ BlinkingLightCollection.

في ListBox الخاص بي، أرغب بشكل أساسي في عرض كل كائن BlinkingLight كعنصر تحكم مخصص يشبه الصندوق المزود بمصباح LED يحتوي على رسم متحرك يجعل مؤشر LED يبدو وكأنه يومض لثانية واحدة ثم يعود إلى الوضع الطبيعي.

تحتوي فئة BlinkingLight الخاصة بي على كائن "LED" تابع لجهة خارجية يثير حدثًا يسمى "Flash".

أنا أبحث عن أفكار أو حلول للحصول على هذا العمل!

محاولتي الفاشلة:

لقد قمت بإنشاء عنصر تحكم مخصص (BlinkingLightControl) يمكنه الارتباط ببيانات فئة BlinkingLight الخاصة بي عندما يكون BlinkingLight هو DataContext لعنصر التحكم المخصص الخاص بي.

لقد قمت بإنشاء DataTemplate لـ ListBox الخاص بي:

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

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

ملحوظة:يمكنني فقط وضع xaml لعنصر التحكم المخصص الخاص بي في قالب البيانات بدلاً من الحصول على عنصر تحكم مختلف تمامًا إذا كان ذلك يجعل الأمور أسهل.

الآن أريد الحصول على EventTrigger في BlinkingLightControl (أو DataTemplate) الذي يمثل RoutedEvent حدث LED.Flash.لسوء الحظ لا يبدو أنني أستطيع معرفة هذا الجزء.لقد حاولت إنشاء RoutedEvent في صف BlinkingLight الخاص بي ورفعه عندما أتعامل مع حدث LED.Flash.ومع ذلك، فإن صفي ليس UIElement أو ContentElement، ووفقًا لـ MSDN: رابط ام اس ان دي

"يمكن أن يكون مالك الحدث الموجه أي فئة، ولكن يجب رفع الأحداث الموجهة ومعالجتها بواسطة الفئات المشتقة من UIElement أو ContentElement لكي تكون مفيدة.لمزيد من المعلومات حول الأحداث المخصصة، راجع كيفية:قم بإنشاء حدث موجه مخصص."

أي مساعدة سيكون موضع تقدير كبير!شكرا ، سكوت

هل كانت مفيدة؟

المحلول 2

لقد تمكنت من التوصل إلى حل نجح بشكل جيد:

نظرًا لأن DataTemplate الخاص بي يحتوي ببساطة على UserControl مخصص (الذي يرتبط بـ DataContext للحصول على بياناته من كائن الأعمال)...لقد وضعت RoutedEvent المخصص الخاص بي في UserControl.ثم في حدث تحميل UserControl الخاص بي، قمت بتحويل DataContext ككائن الأعمال الخاص بي للوصول إلى خاصية كائن الأعمال التي تحتوي على الحدث وربطه بمعالج الحدث.(في المثال الخاص بي، قمت بتحويل DataContext ككائن BlinkingLight، ثم يمكنني الوصول إلى حدث Flash الخاص بخاصية Led الخاصة به وربطه بمعالج حدث مخصص).ملحوظة:يجب أن يكون كائن 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);
    }
}

نصائح أخرى

في هذه الحالة، أفضل طريقة هي استخدام WPF Commanding وإنشاء أمر توجيهي "BlinkTheLights" - سيتعامل BlinkingLightControl مع أمر BlinkTheLights، ويستجيب عن طريق بدء StoryBoard الذي يومض الضوء.

إذا كنت تقوم بإنشاء عنصر تحكم مخصص، فيمكنك دائمًا تعيين المشغل خارج قالب التحكم.

شيء مثل:

  <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>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top