我有一个UserControl,我们称之为myUC
,这是我的WPF应用程序主窗口(myWindow
)中的几个UserControl之一。 myUC
包含许多标准控件,其中一个是按钮,我们称之为myButton
。
当我点击myButton
时,我想执行myMethod()
,它存在于myWindow的代码隐藏中。
问题在于myUC
并不知道myWindow
甚至存在,更不用说myMethod存在了。
我如何发送信息:'嘿,myWindow,醒来。 myUc上的myButton刚刚被点击;请运行myMethod'?
答案 0 :(得分:8)
您可以在窗口中创建命令,并将按钮的Command属性设置为此命令的名称。单击该按钮将触发该命令,而无需引用父窗口。
答案 1 :(得分:5)
我实际上最终不得不在VB中做什么:
为我的自定义命令创建一个新的公共类,因为不希望将我的MainWindow类设为Public:
Public Class Commands
Public Shared myCmd As New RoutedCommand
End Class
创建运行所需代码的Execute和CanExecute方法。这两个方法是在MainWindow代码后面创建的:
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
在MainWindow代码隐藏中创建Command绑定,并将两个处理程序方法添加到绑定中(这是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中似乎不可能,因此我必须在代码隐藏中执行此操作。 Commands类必须是Public,因此可以在此UserControl中访问命令:
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
答案 2 :(得分:4)
我建议您了解Routed Events和Routed Commands - 这是他们打算做的事情。
答案 3 :(得分:3)
以上一切都很好......但对我来说似乎有点令人费解......
我的类似问题: 我有一个带有UserControl(SurveyHeader.xaml)的Window(MainWindow.xaml),其中UserControl是另一个UserControl(GetSurveyByID.xaml)。我在MainWindow.xaml中有一个私有空格,我想在GetSurveyByID.xaml中单击一个按钮(btnGetSurvey)时运行。
这一行解决方案对我来说效果很好。
this.ucSurveyHeader.ucGetSurveyByID.btnGetSurvey.Click += new RoutedEventHandler(btnGetSurvey_Click);
答案 4 :(得分:0)
每个控件都有一个父属性,告诉您实际“拥有”此控件的人。您可以将其与类型转换一起使用来访问myWindow的myMethod 您还可以使用事件处理程序的 sender 参数,如下所示:
(sender as MyWindow).myMethod()
答案 5 :(得分: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);