从用户控件WPF调用主窗口中的公共功能

时间:2014-08-14 07:56:49

标签: c# wpf winforms xaml user-controls

我有一个主窗口,其中包含一些在WPF XAML中初始化的用户控件 的 MainWindow.xaml

<Grid>
    <local:RegularUnit x:Name="ucRegularUnit" Grid.Row="0" />
    <local:Actions x:Name="ucActions" Grid.Row="1" />
    // .....
</Grid>

我在主窗口中有一个公共功能,我想在用户控件中单击一个按钮后调用它。在搜索了一些解决方案之后,我找到了一种在我的User Control类中获取父窗口实例的方法,但是当我使用parentWindow.myFunction()时它找不到该函数。

用户控制RegularUnit.cs

public partial class RegularUnit : UserControl
{
    public RegularUnit()
    {
        InitializeComponent();
    }

    private void Button_SearchSerialNumber_Click(object sender, RoutedEventArgs e)
    {
        Window parentWindow = Window.GetWindow(this);
        //parentWindow.    //Can't find the function myFunction()
    }
}

MainWindow.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    public void myFunction()
    {
        // Do Some Stuff...
    }
}

我做错了什么,我该如何解决?

3 个答案:

答案 0 :(得分:3)

您无法在myFunction上致电parentWindow,因为它不是标准WPF Window课程的成员,而是您的自定义MainWindow成员。

您可以做的是将Window.GetWindow(this)的结果投射到MainWindow,例如

MainWindow parentWindow = (MainWindow)  Window.GetWindow(this);
parentWindow.myFunction();

然而,这是一个非常糟糕的课程设计,因为现在您的用户控制依赖于嵌入特定窗口。

您应该做的是将事件添加到父控件可以订阅的用户控件。

public event EventHandler SerialNumberSearch;

private void Button_SearchSerialNumber_Click(object sender, RoutedEventArgs e)
{
    var handler = SerialNumberSearch;
    if (handler != null) handler(this, EventArgs.Empty);
}

当然,您可以使用不同类型的EventHandler,具体取决于您的需求。

答案 1 :(得分:0)

System.Windows.Application.Current.Windows.OfType<YourWindow>().SingleOrDefault(x => x.IsActive).YourPublicMethod();

虽然上面的代码是一种混乱的方式,但它仍然完成了工作。

答案 2 :(得分:0)

基于Dirk建议的事件订阅的解决方案。我的事件基于一个简单的委托,但是您可以遵循类似的模式并将其基于适合您的情况的委托。

// In UserControl

    namespace TextEditor
    {
        public partial class TextEditorToolBar : UserControl
        {
            // you can use Action type delegate also
            public delegate void getDocumentKeywords(); 
            public event getDocumentKeywords getDocumentRakeKeywordsEvent;

            public TextEditorToolBar()
            {
                InitializeComponent();
            }

            // This is event handloer for the button on your user control
            private void ExtractRakeKeywords(object sender, RoutedEventArgs e)
            {
                 var handler = getDocumentRakeKeywordsEvent;

                 if (getDocumentRakeKeywordsEvent != null)
                     getDocumentRakeKeywordsEvent();
            }
        }
    }

// In MainWindow
namespace TextEditor
{
    public partial class MainWindow : Window
    {
        private DocumentKeywordsExtractor KeyWordsExtractor;
        public MainWindow()
        {
            InitializeComponent();
            KeyWordsExtractor = new DocumentKeywordsExtractor(richTextBox);

            // toolbar is the name given to UserControl in MainWindow.xaml
            toolbar.getDocumentRakeKeywordsEvent += ExtractRakeKeywords;

        }

        private void ExtractRakeKeywords()
        {
            KeyWordsExtractor.GetRakeKeywords();
        }
}