문제

BlinkingLight라는 사용자 정의 클래스가 있습니다.또한 정적 ObservableCollection BlinkingLightCollection도 있습니다.UI에는 BlinkingLightCollection에 바인딩된 ListBox가 있습니다.

내 ListBox에서는 기본적으로 각 BlinkingLight 개체를 LED 조명이 있는 상자처럼 보이는 사용자 정의 컨트롤로 표시하고 싶습니다. 이 컨트롤에는 LED가 잠시 깜박인 것처럼 보이다가 다시 정상으로 돌아가는 것처럼 보이게 만드는 애니메이션이 있습니다.

내 BlinkingLight 클래스에는 'Flash'라는 이벤트를 발생시키는 타사 "LED" 개체가 있습니다.

나는 이것을 작동시키기 위한 아이디어나 해결책을 찾고 있습니다!

나의 실패한 시도:

BlinkingLight가 사용자 지정 컨트롤의 DataContext인 경우 BlinkingLight 클래스의 데이터에 바인딩할 수 있는 사용자 지정 컨트롤(BlinkingLightControl)을 만들었습니다.

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을 데이터 템플릿에 넣을 수 있습니다.

이제 RoutedEvent가 LED.Flash 이벤트인 BlinkingLightControl(또는 DataTemplate)에 EventTrigger를 갖고 싶습니다.아쉽게도 이 부분은 파악하지 못하는 것 같습니다.BlinkingLight 클래스에 RoutedEvent를 생성하고 LED.Flash 이벤트를 처리할 때마다 이를 발생시키려고 했습니다.그러나 내 클래스는 UIElement 또는 ContentElement가 아니며 MSDN에 따라 다음과 같습니다. MSND 링크

"라우팅된 이벤트 소유자는 모든 클래스가 될 수 있지만 라우트된 이벤트가 유용하려면 UIElement 또는 ContentElement 파생 클래스에 의해 발생되고 처리되어야 합니다.사용자 지정 이벤트에 대한 자세한 내용은 방법을 참조하세요.사용자 지정 라우팅 이벤트를 만듭니다."

어떤 도움이라도 대단히 감사하겠습니다!!고마워, 스캇

도움이 되었습니까?

해결책 2

나는 매우 효과적인 해결책을 생각해낼 수 있었습니다.

내 DataTemplate에는 단순히 사용자 지정 UserControl(비즈니스 개체에서 데이터를 가져오기 위해 DataContext에 바인딩됨)이 포함되어 있기 때문에...UserControl에 사용자 지정 RoutedEvent를 배치했습니다.그런 다음 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);
    }
}

다른 팁

이 경우 가장 좋은 방법은 WPF 명령을 사용하고 "BlinkTheLights" RoutedCommand를 만드는 것입니다. 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