代码之家  ›  专栏  ›  技术社区  ›  Stewbob

一个按钮点击一个用户控件如何在包含的窗口中执行一个方法?

  •  8
  • Stewbob  · 技术社区  · 14 年前

    我有一个用户控件,我们称之为 myUC ,这是主窗口中几个用户控件中的一个( myWindow )我的WPF申请。 米尤克 包含许多标准控件,其中一个是按钮,我们称之为 myButton .

    当我点击 我的按钮 ,我想执行 myMethod() 存在于代码库的代码后面。

    问题是 米尤克 我不知道 我的窗口 甚至存在,更不用说My方法存在了。

    我该怎么发信息:“嘿,我的窗户,醒醒。刚刚单击了myUc上的myButton;请运行myMethod'?

    6 回复  |  直到 10 年前
        1
  •  8
  •   Alex B    8 年前

    可以在窗口中创建命令,并将按钮的命令属性设置为此命令的名称。单击该按钮将触发该命令,而不需要引用父窗口。

    This tutorial explains everything very clearly.

        2
  •  5
  •   Stewbob    14 年前

    我最终不得不在VB中做的事情:

    为自定义命令创建新的公共类,因为不希望将主窗口类设置为公共:

    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
    

    将新的自定义命令添加到用户控件上的按钮对象。使用自定义命令,这在XAML中似乎是不可能的,所以我必须在代码后面执行。Commands类需要是公共的,以便可以在此用户控件中访问这些命令:

    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
  •  4
  •   Dan J    14 年前

    我建议你了解 Routed Events Routed Commands -这是他们注定要做的事。

        4
  •  3
  •   JRBlack    13 年前

    以上都很好。。。但我觉得有点复杂。。。

    我的类似问题: 我有一个窗口(MainWindow.xaml)中有一个UserControl(SurveyHeader.xaml),在这个窗口中,UserControl是另一个UserControl(GetSurveyByID.xaml)。我在MainWindow.xaml中有一个私有void,当在GetSurveyByID.xaml中单击按钮(btnGetSurvey)时,我想运行它。

    这条单行线的解决方案对我很有效。

    this.ucSurveyHeader.ucGetSurveyByID.btnGetSurvey.Click += new RoutedEventHandler(btnGetSurvey_Click);
    
        5
  •  0
  •   Maghoumi    14 年前

    每个控件都有一个父属性,该属性告诉您谁实际“拥有”此控件。您可以在类型转换的同时使用它来访问myWindow的myMethod。
    你也可以使用 发件人 事件处理程序的参数如下:

    (sender as MyWindow).myMethod()
    
        6
  •  0
  •   littlekujo    14 年前

    尝试以下静态帮助程序方法:

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