2012-01-07 63 views
6

有時WPF會令人生氣。在WPF窗口和用戶控件之間共享數據的最佳方式是什麼?

我有一個相當簡單的應用程序,它由包含選項卡控件和多個選項卡的單個主窗口組成。我不喜歡在同一個文件中擁有所有選項卡代碼的想法,所以我使用this question的答案將每個選項卡分解爲單獨的用戶控件。

我的主窗口中有一個包含應用程序設置和一些其他應用程序範圍的數據的對象的實例。我的幾個標籤頁需要訪問這些數據才能進行數據綁定。我一直無法找到一個很好的方法來實現這一目標。

首先,我嘗試訪問控制Loaded事件中的父窗口,並獲取對主窗口中暴露設置對象的屬性的引用,如下面的代碼所示。除了Loaded事件以外,這類作品每次標籤獲得焦點時都會被觸發。此外,此事件發生在控件生命週期的後期,因此我無法綁定到用戶控件XAML中此對象的任何屬性。

private void MyUserControl_Loaded(object sender, RoutedEventArgs e) 
{ 
    this.ApplicationSettings = ((MainWindow)Window.GetWindow(this)).ApplicationSettings; 
} 

然後我嘗試將數據傳遞給用戶控件構造函數,但是在XAML中沒有辦法做到這一點。

鑑於這些是應用程序範圍的設置,我可以使ApplicationSettings類成爲singleton並在任何地方引用它,但是我寧願不爲單元測試目的而這樣做。

那麼,如何做到這一點?我的方法是否存在根本上的缺陷?在我看來,所有這些UI元素都是同一個窗口的一部分,因此應該能夠從主窗口訪問數據,但對象模型似乎不允許這樣做。

回答

2

你可以把設置對象爲靜態屬性的包裝類(SettingsHolder在這個例子中,並廣泛引用它的應用程序通過

在XAML:與local

{Binding SettingName, Source={x:Static local:SettingsHolder.Settings}} 

被命名空間的SettingsHolder類是在。

在代碼:

var x = SettingsHolder.Settings.SettingName; 
SettingsHolder.Settings.SettingName = x; 
+0

我認爲這是我要採取的路線。就像我在原帖中所說的那樣,我希望單身人士的行爲沒有實際的單身人士,這就給了我這樣的感覺。實際上,我可能會創建單獨的類,但將構造函數公開用於測試目的。 謝謝! – EricTheRed 2012-01-07 23:18:41

1

在用戶控件的聲明中,您可以將數據上下文設置爲包含所有需要綁定到的東西的對象實例!

<someNamespace:EricsUserControl DataContext="{Binding InstanceOfBindingObject}"/>

然後,它的用戶控件中對象的實例,你通常會就可以訪問屬性。

+0

這真的很好理解,我可能會將其用於其他一些事情,但我想讓選項打開以訪問代碼中的設置。 – EricTheRed 2012-01-07 23:19:47

+0

@EricTheRed非常明智,但只是一個小小的頭腦,您也可以在代碼中訪問DataContext以進行用戶控制。因此,如果你像上面那樣綁定了實例對象,然後在代碼隱藏文件中做了一些小的'var myInstance =(BindingObjectClass)this.DataContext',你就可以從myInstance變量中訪問該對象!希望在未來的某個時候有所幫助! – Kevek 2012-01-07 23:53:17

0

我所做的是在Tab中使用Frame,並在Frame中放置Page。 (但我認爲同樣可以適用於用戶控制)。構造函數僅在創建頁面時觸發,您可以控制何時創建頁面,並且可以在構造函數中傳遞信息。一個頁面有更多的生命週期事件。我也使用Loaded事件來構建UI(它只會觸發一次)。如果您在XAML中綁定頁面,它將在您啓動應用程序時觸發,並且您無法傳遞信息。這是創建一個頁面並在對話框中顯示它,但該頁面可以綁定到一個框架。

 NavigationWindow winSearchXML; 
     using (new WaitCursor()) 
     { 
      winSearchXML = new NavigationWindow(); 
      winSearchXML.Content = new PageSearchResultsXML(GabeLib.GetSearchXML(GabeLib.enumXMLtype.Flat)); 
     } 
     winSearchXML.ShowDialog(); 

我需要說實話,有些時候,我感到我只是不明白一個頁面上的生命週期。所以拿一點鹽來吧。但關鍵是你有構造函數並加載了可能會給你所需要的事件。

+0

這很聰明!我從來沒有想過要做那樣的事情。我認爲我在做什麼,但這有點矯枉過正。謝謝你的想法。 – EricTheRed 2012-01-07 23:21:06

相關問題