所以我想将一些东西从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>
在MainWindow.xaml中,我有类似的内容
<ContentControl ContentTemplate="{StaticResource Test1}"/>
但是现在VS说我不能使用函数“ Button_Click”,因为它不在App.xaml的代码后面。那么如何在App.xaml中从MainWindow调用此函数?
有什么办法吗?我不想要MVVM或Command之类的答案。如果无法解决,那么不幸的是WPF对我没用。
谢谢。
答案 0 :(得分:0)
您无法做到。参见MSDN documentation for Code-Behind:
您编写的事件处理程序必须是由 x:Class标识的名称空间中的局部类。 您不能 限定事件处理程序的名称以指示XAML处理器执行以下操作: 在不同的类范围内查找该处理程序。您也不能使用 静态方法作为事件处理程序。
在WPF中,您可以改用behaviors。
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;
}
}
答案 1 :(得分:0)
这不是最简单的事情,因为WPF希望事情以自己的方式完成。但是,从最简单到最困难的选择很少。
1。什么也不要做
最简单的方法是将数据模板保留在MainWindow.xaml中。
2。使用命令代替事件处理程序
您当前具有如下定义的事件处理程序:
<Button Content="Button1" Click="Button_Click"
“ More-WPF方式”将用具有以下繁琐语法的命令替换Click的事件处理程序:
<Button Content="Test" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.OnClickCommand}"></Button>
然后在MainWindow中定义命令:
public ICommand OnButtonClick
{
get
{
return new Command(() =>
{
this.Text.Text = "Updated";
});
}
}
3。在App.xaml.cs中定义事件处理程序,并使用其路由事件处理程序
我不建议这样做,因为它会使保持同步变得很累,但是有可能。在App.xaml.cs中创建事件处理程序:
public partial class App : Application
{
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
然后使用发送方访问MainWindow实例并调用其方法:
private void Button_Click(object sender, RoutedEventArgs e)
{
var mainWindow = (MainWindow)Window.GetWindow((DependencyObject)sender);
mainWindow.DoWork();
}
在我的第二个示例中,命令的定义如下:
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();
}
}