简体   繁体   English

App.xaml中MainWindow.xaml.cs中的Click-Event

[英]Click-Event from MainWindow.xaml.cs in App.xaml

so i want to outsource some things from MainWindow.xaml to App.xaml like this for example : 所以我想将一些东西从MainWindow.xaml外包给App.xaml,例如:

<Application x:Class="SVGTesting.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <DataTemplate DataType="{x:Type ContentControl}" x:Key="Test1">
                <StackPanel Orientation="Horizontal">
                    <Button Content="Button1" Click="Button_Click" x:Name="Button1"/>
                    <Button Content="Button2" Click="Button_Click" x:Name="Button2"/>
                </StackPanel>
            </DataTemplate>
        </ResourceDictionary>
    </Application.Resources>
</Application>

In MainWindow.xaml then i have something like this 在MainWindow.xaml中,我有这样的内容

<ContentControl ContentTemplate="{StaticResource Test1}"/>

But now VS says that i cannot use the function "Button_Click" because its not in the codebehind from App.xaml. 但是现在VS表示我不能使用功能“ Button_Click”,因为它不在App.xaml的代码背后。 So how can i call this function from MainWindow in App.xaml? 那么如何在App.xaml中从MainWindow调用此函数?

Is there any way? 有什么办法吗? I don't want answers like MVVM or Command. 我不想要MVVM或Command之类的答案。 If it's not possible to solve then WPF is unfortunately useless for me. 如果无法解决,那么不幸的是WPF对我毫无用处。

Thanks and Greetings. 谢谢和问候。

You can't do it. 你做不到 See MSDN documentation for Code-Behind : 有关代码隐藏,请参见MSDN文档

The event handlers you write must be instance methods defined by the partial class within the namespace identified by x:Class. 您编写的事件处理程序必须是由x:Class标识的命名空间中的部分类定义的实例方法。 You cannot qualify the name of an event handler to instruct a XAML processor to look for that handler in a different class scope. 您不能限定事件处理程序的名称来指示XAML处理器在不同的类范围内查找该处理程序。 You also cannot use a static method as an event handler. 您也不能将静态方法用作事件处理程序。

In WPF you can use a behaviors instead. 在WPF中,您可以改用行为

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<Button Content="btnWithBehavior">
    <i:Interaction.Behaviors>
        <local:HandleButtonClick/>
    </i:Interaction.Behaviors>
</Button>

public class HandleButtonClick : Behavior<Button>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.Click += AssociatedObject_Click; ;
    }
    private void AssociatedObject_Click(object sender, RoutedEventArgs e)
    {
        //Move your MainWindow.Button_Click here;
    }
    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.Click -= AssociatedObject_Click;
    }
}

This is not the easiest thing to do as WPF expect things to be done in its own way. 这不是最简单的事情,因为WPF希望事情以自己的方式完成。 But there's few options, from easiest to hardest. 但是,从最简单到最困难的选择很少。

1. Don't do anything 1.什么都不要做

Easiest way is to keep your data templates inside the MainWindow.xaml. 最简单的方法是将数据模板保留在MainWindow.xaml中。

2. Use Commands instead of event handlers 2.使用命令代替事件处理程序

You currently have event handlers defined like this: 当前,您具有如下定义的事件处理程序:

<Button Content="Button1" Click="Button_Click"

"More-WPF way" of doing this would be to replace Click's event handler with a command with this quite cumbersome syntax: 做到这一点的“ More-WPF方法”将是使用以下非常繁琐的语法用命令替换Click的事件处理程序:

        <Button Content="Test" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.OnClickCommand}"></Button>

And then define the command in your MainWindow: 然后在您的MainWindow中定义命令:

    public ICommand OnButtonClick
    {
        get
        {
            return new Command(() =>
            {
                this.Text.Text = "Updated";
            });
        }
    }

3. Define the event handlers in App.xaml.cs and use that to route the event handlers 3.在App.xaml.cs中定义事件处理程序,并使用该事件处理程序路由事件处理程序

I don't recommend this as it get tiresome to keep things synced but it's possible. 我不建议这样做,因为它会使保持同步变得很累,但是有可能。 Create and event handler in App.xaml.cs: 在App.xaml.cs中创建事件处理程序:

public partial class App : Application
{
    private void Button_Click(object sender, RoutedEventArgs e)
    {

    }
}

Then use the sender to access the MainWindow instance and call it's method: 然后使用发送者访问MainWindow实例并调用其方法:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var mainWindow = (MainWindow)Window.GetWindow((DependencyObject)sender);

        mainWindow.DoWork();
    }

In my second example Command is defined like the following: 在我的第二个示例中,命令的定义如下:

    public class Command : ICommand
    {
        public delegate void ICommandOnExecute();
        private ICommandOnExecute _execute;

        public event EventHandler CanExecuteChanged;

        public Command(ICommandOnExecute onExecuteMethod)
        {
            _execute = onExecuteMethod;
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            _execute?.Invoke();
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM