2010-11-16 60 views
8

我有一個UserControl,我們將其稱爲myUC,這是我的WPF應用程序的主窗口(myWindow)中的幾個UserControl之一。 myUC包含許多標準控件,其中一個是按鈕,我們將其稱爲myButton單擊UserControl上的按鈕如何在包含的窗口中執行方法?

當我點擊myButton時,我想執行myMethod(),它存在於myWindow的代碼隱藏中。

問題是myUC不知道myWindow甚至存在,更不用說myMethod存在。

我該如何發送消息:'嘿,myWindow,醒來。 myUc上的myButton只是被點擊;請運行myMethod'?

回答

8

您可以在窗口中創建一個命令,並將該按鈕的Command屬性設置爲該命令的名稱。點擊按鈕將激發該命令,而不需要對父窗口的引用。

This tutorial explains everything very clearly.

+0

Yp,另外404個答案,這次甚至接受! – Rbjz 2016-03-29 10:01:05

+2

我從「The Wayback Machine」互聯網檔案中挖出了文章。不確定最好的辦法是在網站不再存在時避免斷開的鏈接,並且文章的內容太多而無法包含在這裏。 https://web.archive.org/web/20121102095816/http://www.switchonthecode.com/tutorials/wpf-tutorial-command-bindings-and-custom-commands – 2016-03-30 12:59:16

+0

本教程有點太多的閱讀我的胃口。我建議舉個實例。 – Rbjz 2016-03-31 06:52:13

0

每個控件都有一個父屬性,告訴你誰實際擁有這個控件。你可以使用類型轉換來訪問你的myWindow的myMethod。
你也可以用你的事件處理程序的發送的說法是這樣的:

(sender as MyWindow).myMethod() 
+0

我試過這種方法,並從System.Windows.Controls.Button得到一個NullReferenceException。 – wonea 2012-10-16 11:50:25

4

我建議學習Routed EventsRouted Commands - 這是哪門子的他們的意思做的事情。

+0

您是否想要鏈接到「MSDN Magazine期刊與下載」?如果你包含一個小例子,它會是一個很好的答案。 – Rbjz 2016-03-29 10:02:56

+0

@Rbjz Nope,自從我發佈該鏈接後,看起來就像是這個鏈接已經損壞。我看到你對接受答案的評論,並同意沮喪。不幸的是,七年來,我無法通過一個例子來改進這個答案。 – 2018-02-07 23:22:36

0

嘗試是這樣的靜態輔助方法:

public static T GetParentOfType<T>(DependencyObject currentObject) 
     where T : DependencyObject 
    { 
     // Get the parent of the object in question 
     DependencyObject parentObject = GetParentObject(currentObject); 

     if (parentObject == null) 
      return null; 

     // if the parent is the type then return 
     T parent = parentObject as T; 
     if (parent != null) 
     { 
      return parent; 
     } 
     else // if not the type, recursively continue up 
     { 
      return GetParentOfType<T>(parentObject); 
     } 
    } 
    public static DependencyObject GetParent(DependencyObject currentObject) 
    { 
     if (currentObject == null) 
      return null; 
     // Convert the object in question to a content element 
     ContentElement contentEl = currentObject as ContentElement; 

     if (contentEl != null) 
     { 
      // try dependencyobject 
      DependencyObject parent = System.Windows.ContentOperations.GetParent(contentEl); 
      if (parent != null) 
       return parent; 

      // Convert the contentEl to a FrameworkContentElement 
      FrameworkContentElement frameworkEl = contentEl as FrameworkContentElement; 
      // try frameworkcontentelement 
      if (frameworkEl != null) 
       return frameworkEl.Parent; 
      else 
       return null; 
     } 

     // couldn't get the content element, so return the parent of the visual element 
     return System.Windows.Media.VisualTreeHelper.GetParent(currentObject); 
    } 

執行它,像這樣:

StaticHelpers.GetParentOfType<Window>(this); 
5

什麼其實我最後不得不在VB做:

爲我的自定義命令創建一個新的公共類,因爲它是u無需將我的MainWindow類設置爲Public:

Public Class Commands 
    Public Shared myCmd As New RoutedCommand 
End Class 

創建運行所需代碼的Execute和CanExecute方法。

Class MainWindow 

Private Sub myCmdCanExecute(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs) 
    e.CanExecute = True 
    e.Handled = True 
End Sub 

Private Sub myCmdExecuted(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs) 
    //Do stuff here... 
    e.Handled = True 
End Sub 

End Class 

創建命令在主窗口綁定代碼隱藏和兩個處理方法添加到綁定(這是C#和VB之間完全不同的部分:在後面的主窗口的代碼創建了這兩個方法):

Class MainWindow 
Public Sub New() 
     // This call is required by the designer. 
     InitializeComponent() 
     //Add any initialization after the InitializeComponent() call. 
     //Create command bindings. 
     Dim cb As New CommandBinding(Commands.myCmd) 
     AddHandler cb.CanExecute, AddressOf myCmdCanExecute 
     AddHandler cb.Executed, AddressOf myCmdExecuted 
     Me.CommandBindings.Add(cb) 
End Sub 
End Class 

將新的自定義命令添加到UserControl上的按鈕對象。使用自定義命令,這在XAML中似乎不可行,所以我必須在代碼隱藏方面做到這一點。所需要的命令類是公共所以命令是在這個用戶控件訪問:

Public Class myUserControl 
    Public Sub New() 
    //This call is required by the designer. 
    InitializeComponent() 
    // Add any initialization after the InitializeComponent() call. 
    myButton.Command = Commands.myCmd 
    End Sub 
End Class 
3

以上是一切都很好......但似乎有點令人費解,我...

我類似的問題: 我有一個窗口(MainWindow.xaml),在它用戶控件(SurveyHeader.xaml)和用戶控件裏面是另一個用戶控件(GetSurveyByID.xaml)。我在MainWindow.xaml中有一個私有的void,當我在GetSurveyByID.xaml中點擊一個按鈕(btnGetSurvey)時,我想運行它。

這一行解決方案對我來說效果很好。

this.ucSurveyHeader.ucGetSurveyByID.btnGetSurvey.Click += new RoutedEventHandler(btnGetSurvey_Click); 
+0

體面的答案。這些天我使用路由事件而不是命令來滿足這種需求。 – Stewbob 2011-06-03 20:00:47

相關問題