2014-03-27 6 views
0

Singleton 클래스가 커서 좌표를 읽고이를 사용하는 Observer 클래스를 레이블에 게시하는 WPF 응용 프로그램을 작성했습니다.WPF, EventAggregator 대신 커서 읽기 위치 커서 위치

좌표를 읽기위한 싱글 톤 클래스에서 이제 타이머를 사용하고 있습니다. MouseMoveEvent를 사용하는 EventAggregator에 의해 그를 대체하고 싶습니다. 튜토리얼을 많이 읽었지만 EventAggregator가 작동하는 방식과 내 앱에 맞는 방식을 이해하지 못합니다. 아무도 내 예제에서 설명 할 수 있을까?

싱글 :

public class MousePointProvider 
{ 
    [DllImport("user32.dll")] 
    static extern bool GetCursorPos(ref System.Drawing.Point lpPoint); 

    private List<IObserver> _observerList; 
    private DispatcherTimer _timer; 

    private static MousePointProvider _instance = null; 
    public static MousePointProvider Instance 
    { 
     get 
     { 
      if (_instance == null) 
      { 
       _instance = new MousePointProvider(); 
      } 
      return _instance; 
     } 
    } 

    private Point _currentMousePosition; 
    public Point CurrentMousePosition 
    { 
     get { return _currentMousePosition; } 
    } 

    private MousePointProvider() 
    { 
     _observerList = new List<IObserver>(); 

     _timer = new DispatcherTimer(); 
     _timer.Interval = TimeSpan.FromMilliseconds(1); 
     _timer.Tick += (s, e) => 
      { 
       MousePositionChanged(); 
      }; 

     _timer.Start(); 
    } 

    public void RegisterObserver(IObserver observer) 
    { 
     if (!_observerList.Contains(observer)) 
     { 
      _observerList.Add(observer); 
     } 
    } 

    public void UnregisterObserver(IObserver observer) 
    { 
     _observerList.Remove(observer); 
    } 

    public void MousePositionChanged() 
    { 
     GetCursorPos(ref _currentMousePosition); 

     for (int i = 0; i < _observerList.Count; i++) 
     { 
      _observerList[i].MouseChanged(_currentMousePosition.X, _currentMousePosition.Y); 
     } 
    } 
} 

관찰자 : 사전에

public class Listener : Canvas, IObserver 
{ 
    System.Windows.Controls.Label labelX = new System.Windows.Controls.Label(); 
    System.Windows.Controls.Label labelY = new System.Windows.Controls.Label(); 

    public Listener() 
    { 
     MousePointProvider.Instance.RegisterObserver(this); 

     this.Children.Add(labelX); 
     Canvas.SetLeft(labelX, 100); 
     Canvas.SetTop(labelX, 100); 

     this.Children.Add(labelY); 
     Canvas.SetLeft(labelY, 100); 
     Canvas.SetTop(labelY, 200); 
    } 

    public void MouseChanged(int x, int y) 
    { 
     labelX.Content = "X=" + x.ToString(); 
     labelY.Content = "Y=" + y.ToString(); 
    } 

}

덕분에 여기에 코드입니다.

답변

0

프리즘 WPF 프레임 워크를 살펴볼 수 있습니다. 거기에 많은 것들이 있지만, 당신이 관심있는 것은 EventAggregator라는 클래스입니다.

EventAggregator를 사용하면 다른 클래스에서 "구독 할 수있는"이벤트를 "게시"할 수 있습니다. 그러나 기존 .Net 이벤트와 달리 구독자는 이벤트를 발생시키는 개체에 이벤트 처리기를 직접 연결하지 않습니다. EventAggregator는 중개자 역할을하므로 게시자 또는 구독자는 서로를 인식 할 필요가 없습니다.

은 게시 및 구독 한 - 라이너가 있지만 이상하게 복잡한, 그래서 조금 일을 단순화하는 헬퍼 클래스에 EventAggregator 포장

을 : -

public class EventAggregatorWrapper 
{ 
    private EventAggregator _eventAggregator = new EventAggregator(); 

    // Publish 
    public void Publish<TEvent>(TEvent eventToPublish) 
    { 
     GetEvent<TEvent>().Publish(eventToPublish); 
    } 

    // Subscribe 
    public SubscriptionToken Subscribe<TEvent>(
     Action<TEvent> action, 
     ThreadOption threadOption = ThreadOption.PublisherThread, 
     bool keepSubscriberReferenceAlive = false, 
     Predicate<TEvent> filter = null) 
    { 
     return GetEvent<TEvent>().Subscribe(action, threadOption, keepSubscriberReferenceAlive, filter); 
    } 

    // Unsubscribe 
    public void Unsubscribe<TEvent>(SubscriptionToken token) 
    { 
     GetEvent<TEvent>().Unsubscribe(token); 
    } 

    // Helper method to get a CompositePresentationEvent to act upon. 
    private CompositePresentationEvent<TEvent> GetEvent<TEvent>() 
    { 
     return _eventAggregator.GetEvent<CompositePresentationEvent<TEvent>>(); 
    } 
} 

다음, 클래스를 만들 OU 필요는 당신을 대표 이벤트 "메시지"(있는 EventArgs 같은 비트 개체), 예 :

다음
public class CursorMovedMessage 
{ 
    public Point NewPosition { get; set; } 
} 

가 이벤트를 게시 할 수 : -

var msg = new CursorMovedMessage(); 
msg.NewPosition = new Point(mouse.X, mouse.Y); 

_eventAggregatorWrapper.Publish(msg); 

A "소비자"이 같은 이러한 메시지를 구독 할 것이다 : -

_eventAggregatorWrapper.Subscribe<CursorMovedMessage>(CursorMovedMessageHandler, ThreadOption.BackgroundThread); 

private void CursomrMovedMessageHandler(CursorMovedMessage msg) 
{ 
    // Do something with the message object here 
} 

은 가입자가 대리자를 실행하는 스레드를 지정할 수 있습니다 (예를 들어, UI 스레드, b/g 스레드 등).