2010-11-16 25 views
8

Tôi có một UserControl, chúng tôi sẽ gọi nó là myUC, đó là một trong một số UserControls trong cửa sổ chính (myWindow) của ứng dụng WPF của tôi. myUC chứa một số điều khiển tiêu chuẩn, một trong số đó là nút, chúng tôi sẽ gọi nó là myButton.Làm thế nào một nút bấm trên một UserControl có thể thực hiện một phương thức trong cửa sổ chứa?

Khi tôi nhấp vào myButton, tôi muốn thực thi myMethod(), tồn tại trong mã phía sau myWindow.

Vấn đề là myUC không có bất kỳ ý tưởng nào rằng myWindow thậm chí còn tồn tại, ít hơn nhiều so với myMethod.

Làm cách nào để gửi tin nhắn: 'Hey, myWindow, hãy thức dậy. myButton trên myUc vừa được nhấp; hãy chạy myMethod '?

Trả lời

8

Bạn có thể tạo lệnh trong cửa sổ và đặt thuộc tính Lệnh của nút thành tên của lệnh này. Nhấp vào nút sẽ kích hoạt lệnh, mà không cần tham chiếu đến cửa sổ chính.

This tutorial explains everything very clearly.

+0

Yp, một câu trả lời 404 khác, lần này thậm chí được chấp nhận! – Rbjz

+2

Tôi đã đào bài viết từ kho lưu trữ Internet "The Wayback Machine". Bạn không chắc chắn cách tốt nhất là tránh các liên kết bị hỏng khi trang web không còn tồn tại và nội dung của bài viết quá nhiều để đưa vào đây. https://web.archive.org/web/20121102095816/http://www.switchonthecode.com/tutorials/wpf-tutorial-command-bindings-and-custom-commands –

+0

hướng dẫn có quá nhiều đọc để sự thèm ăn của tôi. Tôi đề nghị đưa ra một ví dụ làm việc. – Rbjz

0

Mọi điều khiển đều có thuộc tính gốc cho bạn biết rằng ai thực sự "sở hữu" kiểm soát này. Bạn có thể sử dụng cùng với kiểu đúc để truy cập myMindhod của myWindow.
Bạn cũng có thể sử dụng gửi đối số của bộ xử lý sự kiện của bạn như thế này:

(sender as MyWindow).myMethod() 
+0

Tôi đã thử phương pháp này và nhận NullReferenceException từ System.Windows.Controls.Button. – wonea

4

tôi khuyên bạn nên tìm hiểu về Routed EventsRouted Commands - đây là loại điều họ đang có nghĩa là để làm.

+0

Ý của bạn là liên kết tới "Các vấn đề và tải xuống của tạp chí MSDN"? Nó sẽ làm cho một câu trả lời tuyệt vời nếu bạn bao gồm một ví dụ nhỏ. – Rbjz

+0

@Rbjz Không, có vẻ như liên kết đó đã bị hỏng kể từ khi tôi đăng nó. Tôi thấy nhận xét của bạn về câu trả lời được chấp nhận và đồng ý với sự thất vọng. Thật không may, bảy năm sau, tôi không ở trong một vị trí để cải thiện câu trả lời này với một ví dụ. –

0

Hãy thử một cái gì đó giống như phương pháp này helper tĩnh:

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); 
    } 

Execute nó như vậy:

StaticHelpers.GetParentOfType<Window>(this); 
5

Những gì tôi thực sự đã kết thúc phải làm gì trong VB:

Tạo một lớp công khai mới cho các lệnh tùy chỉnh của tôi vì nó là u mong muốn có lớp MainWindow của tôi là Công khai:

Public Class Commands 
    Public Shared myCmd As New RoutedCommand 
End Class 

Tạo các phương thức Execute và CanExecute chạy mã mong muốn. Hai phương pháp được tạo ra trong các mã MainWindow đằng sau:

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 

Tạo Bộ Tư lệnh ràng buộc trong MainWindow code-behind và thêm hai phương pháp xử lý để các ràng buộc (đây là phần mà là khá khác nhau giữa C# và 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 

Thêm lệnh tùy chỉnh mới vào đối tượng nút trên UserControl. Với một lệnh tùy chỉnh, điều này dường như không thể thực hiện được trong XAML, vì vậy tôi phải làm điều đó trong đoạn mã sau. Lớp Lệnh cần phải được Công khai để các lệnh có thể truy cập được trong UserControl này:

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

Ở trên là tất cả tốt và tốt ... nhưng có vẻ hơi phức tạp với tôi ...

vấn đề tương tự của tôi: Tôi có một cửa sổ (MainWindow.xaml) với một usercontrol (SurveyHeader.xaml) trong đó và bên trong UserControl đó là một UserControl (GetSurveyByID.xaml). Tôi có một khoảng trống riêng trong MainWindow.xaml mà tôi muốn chạy khi một nút (btnGetSurvey) được nhấp vào GetSurveyByID.xaml.

Giải pháp một dòng này hoạt động khá tốt đối với tôi.

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

Câu trả lời rõ ràng. Những ngày này tôi đang sử dụng sự kiện định tuyến thay vì lệnh cho hầu hết các nhu cầu của tôi về loại này. – Stewbob

Các vấn đề liên quan