Pergunta

Eu tenho uma classe personalizada chamada BlinkingLight. Eu também tenho um BlinkingLightCollection ObservableCollection estática. Na interface do usuário, eu tenho uma caixa de listagem que é obrigado a BlinkingLightCollection.

Na minha ListBox eu quero mostrar, essencialmente, cada objeto BlinkingLight como um controle personalizado que se parece com caixa com uma luz LED que tem uma animação que faz o olhar LED como ele apenas passou por um segundo, em seguida, vai voltar ao normal.

classe Meu BlinkingLight tem terceiros "LED" objeto que gera um evento chamado 'Flash'.

Eu estou procurando idéias ou soluções para chegar a este trabalho!

Minha tentativa falhou:

Eu criei um controle personalizado (BlinkingLightControl) que pode se ligar aos dados da minha classe BlinkingLight quando um BlinkingLight é o DataContext do meu controle personalizado.

Eu criei um DataTemplate para o meu 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 apenas colocar o XAML para o meu controle personalizado para o datatemplate em vez de ter um controle completamente diferente se isso faz as coisas mais fáceis

Agora, eu quero ter um EventTrigger em minha BlinkingLightControl (ou DataTemplate), que é RoutedEvent é o evento LED.Flash. Infelizmente eu não consigo entender essa parte para fora. Eu tentei criar um RoutedEvent na minha classe BlinkingLight e apenas levantá-lo sempre que eu manipular o evento LED.Flash. No entanto a minha classe não é um UIElement ou ContentElement, e por MSDN: MSND link

"O proprietário evento roteado pode ser qualquer classe, mas os eventos roteados deve ser suscitada e manipulados por UIElement ou ContentElement classes derivadas, a fim de ser útil Para mais informações sobre eventos personalizados, consulte Como:. Criar um evento roteado personalizado . "

Qualquer ajuda seria muito apreciada !! Obrigado, Scott

Foi útil?

Solução 2

Eu era capaz de chegar a uma solução que tem funcionado muito bem:

Desde o meu DataTemplate simplesmente contém um UserControl personalizado (que se liga ao DataContext para obter seus dados a partir do objeto de negócios) ... Eu coloquei minha RoutedEvent personalizado no UserControl. Então, em evento carregado de meu UserControl, lancei o DataContext como meu objeto de negócios para obter acesso à propriedade do objeto de negócios que tem o evento e ligá-lo a um manipulador de eventos. (No meu exemplo lancei o DataContext como um objeto BlinkingLight, então eu posso obter acesso para o Flash evento de sua propriedade Liderados e ligá-lo a um manipulador de eventos personalizado). Nota:. O objeto LED deve ser uma propriedade, não apenas um campo no objeto BlinkingLight para que ele funcione

Em seguida, o manipulador de eventos pode elevar costume do UserControl evento roteado (FlashGreenEvent). Abaixo está o código de back-end que agora complementa o código no OP (Eu retirados qualquer outro código irrelevante).

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

Outras dicas

Neste caso, a melhor maneira é usar WPF comandante e criar um "BlinkTheLights" RoutedCommand - seu BlinkingLightControl irá lidar com as BlinkTheLights de comando, e responder, iniciando um storyboard que faz piscar a luz.

Se você está fazendo um controle personalizado que você poderia sempre definir o exterior gatilho do modelo de controle.

algo como:

  <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>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top