参考地址:https://www.cnblogs.com/Jaasdsa/p/6164200.html
这篇文章中,最后一个方法,利用反射来使得每个子页面都能访问主页面的介绍中,所给出的代码运行会失败,提示非静态方法需要一个目标。
下面给出的程序已经对此进行了修复。可以正常运行。
前台:
<Window x:Class="WPFClient.App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFClient.App"
mc:Ignorable="d"
Title="MainWindow" Height="480" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<WrapPanel Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Tag="Home" Width="40" Height="40" Margin="5" Click="btnNav_Click">首页</Button>
<Button Tag="SimpleChat" Width="40" Height="40" Margin="0,0,5,0" Click="btnNav_Click">内容</Button>
</WrapPanel>
<Grid Grid.Row="1" Grid.ColumnSpan="3">
<Frame Name="frmMain" NavigationUIVisibility="Hidden"></Frame>
</Grid>
</Grid>
</Window>
后台:
namespace WPFClient.App
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Navigate("Home");
}
#region 页面导航
private void btnNav_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
Navigate(btn.Tag.ToString());
}
private void Navigate(string path)
{
string uri = "WPFClient.App.Views." + path;
Type type = Type.GetType(uri);
if (type != null)
{
//实例化Page页
// object obj = type.Assembly.CreateInstance(uri);
object obj = Activator.CreateInstance(type);
Page control = obj as Page;
this.frmMain.Content = control;
PropertyInfo[] infos = type.GetProperties();
foreach (PropertyInfo info in infos)
{
//将MainWindow设为page页的ParentWin
if (info.Name == "ParentWindow")
{
info.SetValue(control, this, null);
break;
}
}
}
}
#endregion
//公共方法
public void CallFromChild(string name)
{
MessageBox.Show("Hello," + name + "!");
}
}
}
创建一个类:
namespace WPFClient.App
{
public class BasePage : Page
{
#region 父窗体
private MainWindow _parentWin;
public MainWindow ParentWindow
{
get { return _parentWin; }
set { _parentWin = value; }
}
#endregion
}
}
子页的前台
<base:BasePage x:Class="WPFClient.App.Views.Home"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFClient.App.Views"
xmlns:base="clr-namespace:WPFClient.App"
mc:Ignorable="d" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<WrapPanel Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBox Name="txtParam" Width="120" Height="30"></TextBox>
<Button Name="btnCall" Width="90" Height="30" Margin="5" Click="btnCall_Click">CallApiByGet</Button>
</WrapPanel>
<Grid Grid.Row="1">
</Grid>
</Grid>
</base:BasePage>
子页的后台
namespace WPFClient.App.Views
{
/// <summary>
/// Home.xaml 的交互逻辑
/// </summary>
public partial class Home : BasePage
{
public Home()
{
InitializeComponent();
}
private void btnCall_Click(object sender, RoutedEventArgs e)
{
string param = txtParam.Text;
ParentWindow.CallFromChild(param);
}
}
}
这种方案使得Page页访问MainWindow中的公共属性、控件元素或公共变量也是可行的。
此外将BasePage的基类从Page改成UserControl也是可以的