Domanda

Ho una classe personalizzata chiamata BlinkingLight. Ho anche un ObservableCollection statico BlinkingLightCollection. Nell'interfaccia utente ho un ListBox associato a BlinkingLightCollection.

Nel mio ListBox voglio essenzialmente visualizzare ogni oggetto BlinkingLight come un controllo personalizzato che assomiglia a una scatola con una luce a LED che ha un'animazione che fa sembrare il LED appena acceso per un secondo, quindi torna alla normalità.

La mia classe BlinkingLight ha "LED" di terze parti oggetto che genera un evento chiamato "Flash".

Sto cercando idee o soluzioni per farlo funzionare!

Il mio tentativo fallito:

Ho creato un controllo personalizzato (BlinkingLightControl) che può essere associato ai dati della mia classe BlinkingLight quando un BlinkingLight è il DataContext del mio controllo personalizzato.

Ho creato un DataTemplate per il mio ListBox:

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

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

Nota: posso semplicemente inserire xaml per il mio controllo personalizzato nella piastra dati invece di avere un controllo completamente diverso se ciò semplifica le cose.

Ora voglio avere un EventTrigger nel mio BlinkingLightControl (o DataTemplate) il cui RoutedEvent è l'evento LED.Flash. Sfortunatamente non riesco a capire questa parte. Ho provato a creare un RoutedEvent nella mia classe BlinkingLight e sollevarlo ogni volta che gestisco l'evento LED.Flash. Tuttavia la mia classe non è un UIElement o ContentElement e per MSDN: MSND Link

" Il proprietario dell'evento indirizzato può essere qualsiasi classe, ma gli eventi indirizzati devono essere generati e gestiti dalle classi derivate da UIElement o ContentElement per essere utili. Per ulteriori informazioni sugli eventi personalizzati, vedi Procedura: creare un evento indirizzato personalizzato. & Quot;

Qualsiasi aiuto sarebbe molto apprezzato !! Grazie, Scott

È stato utile?

Soluzione 2

Sono stato in grado di trovare una soluzione che ha funzionato abbastanza bene:

Dato che il mio DataTemplate contiene semplicemente un UserControl personalizzato (che si lega a DataContext per ottenere i suoi dati dall'oggetto business) ... Ho inserito il mio RoutedEvent personalizzato in UserControl. Quindi, nell'evento caricato di UserControl, lancio DataContext come oggetto business per ottenere l'accesso alla proprietà dell'oggetto business che ha l'evento e collegarlo a un gestore eventi. (nel mio esempio ho lanciato DataContext come oggetto BlinkingLight, quindi posso accedere all'evento Flash della sua proprietà Led e collegarlo a un gestore eventi personalizzato). Nota: l'oggetto LED deve essere una proprietà, non solo un campo nell'oggetto BlinkingLight affinché funzioni.

Quindi il gestore eventi può generare l'evento indirizzato personalizzato di UserControl (FlashGreenEvent). Di seguito è riportato il codice di back-end che ora integra il codice nell'OP (ho eliminato qualsiasi altro codice irrilevante).

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);
    }
}

Altri suggerimenti

In questo caso, il modo migliore è utilizzare il comando WPF e creare un "BlinkTheLights" RoutedCommand: BlinkingLightControl gestirà il comando BlinkTheLights e risponderà avviando uno StoryBoard che fa lampeggiare la luce.

Se stai eseguendo un controllo personalizzato, puoi sempre impostare il trigger al di fuori del modello di controllo.

qualcosa del tipo:

  <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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top