2010-11-16 12 views
8

Bir UserControl'im var, bunu WPF uygulamamın ana penceresindeki (myWindow) birkaç UserControls arasından biri olan myUC olarak adlandıracağız. myUC, bunlardan biri düğme olmak üzere bir dizi standart kontrol içerir, biz buna myButton deriz.UserControl üzerindeki bir tuşa tıklayarak içerdeki pencerede nasıl bir yöntem uygulayabilirsiniz?

myButton'u tıklattığımda, myWindow kodunun arkasında bulunan myMethod()'u çalıştırmak istiyorum.

myUC'un sorunu, myWindow'un bile mevcut olduğu ve myMethod'un daha az olduğu konusunda herhangi bir fikri yoktur.

Mesajı nasıl gönderebilirim: 'Hey, myWindow, uyandırma. myUcton myUnusu tıklanmıştı; lütfen myMethod'u çalıştırın

cevap

8

Pencerede bir komut oluşturabilir ve düğmenin Command özelliğini bu komutun adına ayarlayabilirsiniz. Düğmeye tıklamak, üst pencereye bir başvuru gerektirmeden komutu tetikler.

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

böylece gibi yürütün:

This tutorial explains everything very clearly.

+0

Yp, başka bir 404 cevabı, bu sefer bile kabul! – Rbjz

+2

"The Wayback Machine" internet arşivinden makaleyi kazdım. Web sitesinin artık mevcut olmaması ve makalenin içeriğinin burada yer alması için çok fazla şey olduğundan emin olun. https://web.archive.org/web/20121102095816/http://www.switchonthecode.com/tutorials/wpf-tutorial-command-bindings-and-custom-commands –

+0

Eğiticinin okuması çok fazladı. iştahım Çalışan bir örnek vermeyi teklif ettim. – Rbjz

0

Her denetimde, bu denetimi kimin gerçekte "sahibi" olduğunu söyleyen bir ebeveyn özelliği vardır. MyWindow'unuzun myMethod'unuza erişmek için bu tipte yazıyla birlikte kullanabilirsiniz.
Ayrıca bu gibi olay işleyicisi gönderen argüman kullanabilirsiniz: Ben öğrenmeyi tavsiye eden

(sender as MyWindow).myMethod() 
+0

Bu yaklaşımı denedim ve System.Windows.Controls.Button bir NullReferenceException aldım. – wonea

4

yaklaşık Routed Events ve Routed Commands - Bu yapmaları yaratılmışız türden bir şey olduğunu.

+0

"MSDN Dergisi Sorunları ve Yüklemeleri" ne demek istediniz? Küçük bir örnek eklediyseniz harika bir cevap olur. – Rbjz

+0

@Rbjz Nope, yayınladığımdan beri bu bağlantı koptu. Kabul edilen cevap hakkındaki yorumlarınızı görüyorum ve hayal kırıklığına katılıyorum. Ne yazık ki, yedi yıl boyunca, bu cevabı bir örnekle iyileştirecek bir konumda değilim. –

0

bu statik yardımcı yöntemiyle gibi bir şey deneyin

Aslında VB yapmak zorunda sona erdi Ne
StaticHelpers.GetParentOfType<Window>(this); 
5

:

Özel komutlarım için yeni bir Genel Sınıf oluştur, çünkü ndesirable Kamu olarak benim MainWindow sınıf için:

Public Class Commands 
    Public Shared myCmd As New RoutedCommand 
End Class 

Yürütme ve istenen kod çalıştırmasına CanExecute yöntemleri oluşturun.

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 

Arka planda kodlama MainWindow içinde bağlayıcı Command oluşturun ve bu C# ve VB arasındaki oldukça farklıdır parçasıdır (bağlama için iki işleyici yöntemleri eklemek: Bu iki yöntem arkasında MainWindow kodunda oluşturulmuş): UserControl üzerindeki düğme nesnesine yeni özel komut ekleyin. Özel bir komutla, bu XAML'de mümkün görünmüyordu, bu yüzden kodu arkada yapmak zorunda kaldım. komutlar bu UserControl erişilebilir bu yüzden gerekli komutlar sınıfı Kamu olması:

yukarıdaki
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

tüm iyi ve güzel ... ama bana dolambaçlı biraz görünüyor ...

Benim benzer sorun: da onunla ilgili bir UserControl (SurveyHeader.xaml) ile bir Pencere (MainWindow.xaml) sahiptir ve bu UserControl içinde başka UserControl (GetSurveyByID.xaml) 'dir. MainWindow.xaml içinde GetSurveyByID.xaml içinde bir düğme (btnGetSurvey) tıklatıldığında çalıştırmak istediğiniz özel bir boşluk var.

Bu tek hat çözümü benim için gayet iyi çalıştı.

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

İyi cevap. Bu günlerde, bu tür bir çok ihtiyacım için Komutlar yerine Yönlendirilmiş Olayları kullanıyorum. – Stewbob