2014-12-04 53 views
0

我的大部分UserControls和類都需要能夠將條目(日誌)添加到MainWindow中的ObservableCollection,該列表由ListBox綁定。從任何類更新UI而不使用事件

有沒有一種優雅的方式來做到這一點,而不需要將MainWindow傳遞給這些類和控件中的每一個,並且不使用事件,所以我不需要擔心內存泄漏?

編輯: 好主意,我只能通過日誌類,但我仍然希望避免傳遞登錄實例化到每個類。

我希望能夠從任何地方接收消息,保持代碼清潔的一些應用程序範圍內的偵聽器的存在。

+1

是什麼讓你覺得會有'Memory Leaks'你是在編寫代碼的地方,你沒有實現'Auto Disposing of Objects i。使用(){}'或不自己清理對象。'如果你不熟悉如何做,你需要實現INotifyPropertyChanged'然後在這裏你可以開始閱讀'Daniel'[INotifyPropertyChange](http:///msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged。aspx) – MethodMan 2014-12-04 17:16:29

+0

@DJKRAZE不是''=事件處理程序可以將堆中正確放置的對象放在堆中,並防止GC清理它們。這並不是說沒有簡單的解決方案(例如:刪除已添加的處理程序),但有更多方法可以引發內存泄漏,而不是您建議的方式。 – 2014-12-04 17:18:28

+0

你爲什麼要傳遞MainWindow?只要通過日誌。 – Paparazzi 2014-12-04 17:18:34

回答

0

我結束了使用github.com/shiftkey/Reactive.EventAggregator 因爲我已經在我的程序中使用無功,這是很簡單

在主窗口我有

using Reactive.EventAggregator; 
MyEventAggregator.MessageAggregator = new EventAggregator(); 
MyEventAggregator.MessageAggregator.GetEvent<MessageEvent>().Subscribe(se => 
myMessageControl.Add(se) 
); 

再有就是有一個列表框LB

一個用戶控件
using Reactive.EventAggregator; 
public partial class MessageControl : UserControl 
{ 
    public MessageControl() 
    { 
     InitializeComponent(); 
     LB.SetBinding(ListBox.ItemsSourceProperty, new Binding { Source = this.MessageCollection }); 
    } 
    public ObservableCollection<MessageEvent> MessageCollection = new ObservableCollection<MessageEvent>(); 

    public void Add(MessageEvent m) 
    { 
     MessageCollection.Add(m); 
    } 
} 

public class MyEventAggregator 
{ 
    public static EventAggregator MessageAggregator { get; set; } 
    public static void PostMessage(string message) 
    { 
     MessageAggregator.Publish(new MessageEvent(message)); 
    } 
} 

從程序中的任何地方我都可以使用

MyEventAggregator.PostMessage("This message appears in MessageControl's Listbox"); 

它甚至可以簡化,但我希望MessageEvent在將來不僅保存一個字符串。

2

棱鏡爲您提供EventAggregator並負責管理對象。使用聚合器,您只能發佈和訂閱事件。如果您需要傳遞一些數據,您可以將它們與事件一起發佈。

this.eventAggregator.GetEvent<MyEvent>().Publish(myCustomData); 

而訂閱事件時,您還可以包含處理程序來處理數據。

this.eventAggregator.GetEvent<MyEvent>).Subscribe(this.HandleMyCustomData); 

與處置這樣的:

private void HandleMyCustomData(MyCustomData data) { } 

雖然它仍然是基於解決方案的事件比使用傳統的事件和處理更優雅。

在這個環節,你可以找到更詳盡的解釋:http://msdn.microsoft.com/en-us/library/ff921122.aspx

+0

儘管看起來很簡單,但我想嘗試避免將Prism添加到我的解決方案中,以便創建日誌。 – Daniel 2014-12-04 19:47:16

+0

夠公平的。對於任何處於規劃階段而不是實施階段的人來說,這仍然是一個有用的線索。 – PiotrWolkowski 2014-12-04 19:48:39

+0

@Daniel你可以很容易地編寫你自己的簡單EventAggregator。你甚至可以瀏覽互聯網找到一個沒有完整棱鏡的現有網站。 – 2014-12-04 20:19:44

0

是棱鏡EventAggregator是非常好的了這樣的事情。

但是,如果您不想啜飲Prism Kool-Aid,另一種可行的方法是讓您的MainWindow註冊一個自定義的TraceListener,並讓其他代碼使用Trace方法來填充日誌。然後,MainWindow TraceListener可以使用Trace數據執行任何您想要的操作。