在WPF开发中,经常遇到这种场景:有两个窗口,比如A,B窗口,都需要共用一个属性值,那么在A窗口打开时,把这个属性值赋值,此时,在A窗口中再打开B窗口,B窗口也要使用这个属性值,有什么常见的实现方法吗?
方法1:可以使用 Application 类的 Properties 集合来保存全局变量
在 WPF 中,可以使用 Application 类的 Properties 集合来保存全局变量,这些变量可以在整个应用程序中共享。
具体实现方法如下:
在 App.xaml.cs 文件中,添加一个静态属性来保存需要共享的属性值。例如,假设需要共享的属性值为一个字符串类型的变量 SharedValue,则可以这样定义:
public partial class App : Application
{
public static string SharedValue { get; set; }
// ...
}
在 A 窗口打开时,将属性值赋值给 App.SharedValue:
private void OpenBWindowButton_Click(object sender, RoutedEventArgs e)
{
// 获取属性值
string sharedValue = GetSharedValue();
// 将属性值赋值给 App.SharedValue
App.SharedValue = sharedValue;
// 打开 B 窗口
BWindow bWindow = new BWindow();
bWindow.ShowDialog();
}
在 B 窗口中,直接访问 App.SharedValue 来获取属性值:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 获取属性值
string sharedValue = App.SharedValue;
// 使用属性值
UseSharedValue(sharedValue);
}
这样,当在 A 窗口中打开 B 窗口时,B 窗口就可以访问到已经保存在 App.SharedValue 中的属性值。由于 App.SharedValue 是一个静态属性,因此它将在整个应用程序中共享。
方法2:事件或者委托来实现
除了使用 Application.Properties 来保存全局变量以外,还可以使用事件或者委托来实现两个窗口之间的通信。
具体实现方法如下:
在 A 窗口中定义一个事件,用于传递需要共享的属性值。例如,假设需要共享的属性值为一个字符串类型的变量 SharedValue,则可以这样定义事件:
public event EventHandler<string> SharedValueChanged;
//在 A 窗口打开时,将属性值传递给事件:
private void OpenBWindowButton_Click(object sender, RoutedEventArgs e)
{
// 获取属性值
string sharedValue = GetSharedValue();
// 触发事件,传递属性值
SharedValueChanged?.Invoke(this, sharedValue);
// 打开 B 窗口
BWindow bWindow = new BWindow();
bWindow.ShowDialog();
}
在 B 窗口中,订阅 A 窗口的事件,以获取属性值:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 订阅 A 窗口的事件
var aWindow = Application.Current.Windows.OfType<AWindow>().FirstOrDefault();
if (aWindow != null)
{
aWindow.SharedValueChanged += AWindow_SharedValueChanged;
}
}
private void AWindow_SharedValueChanged(object sender, string e)
{
// 使用属性值
UseSharedValue(e);
}
这样,当在 A 窗口中打开 B 窗口时,B 窗口就会订阅 A 窗口的事件,从而获取已经传递的属性值。由于事件是在两个窗口之间进行通信的,因此这种方法也可以实现两个窗口之间的数据共享。
方法3:消息机制
除了使用全局变量和事件/委托来实现两个窗口之间的通信以外,还可以使用消息机制。在 WPF 中,可以使用 Messenger 类来实现消息机制,Messenger 类属于 MVVM Light 框架中的一个组件,可以通过 NuGet 包管理器来安装。
具体实现方法如下:
在 A 窗口中,定义一个消息类来传递需要共享的属性值。例如,假设需要共享的属性值为一个字符串类型的变量 SharedValue,则可以这样定义消息类:
public class SharedValueMessage
{
public string SharedValue { get; set; }
}
在 A 窗口打开时,将属性值封装到消息类中,然后发送消息:
private void OpenBWindowButton_Click(object sender, RoutedEventArgs e)
{
// 获取属性值
string sharedValue = GetSharedValue();
// 封装属性值到消息类中
SharedValueMessage message = new SharedValueMessage() { SharedValue = sharedValue };
// 发送消息
Messenger.Default.Send(message);
// 打开 B 窗口
BWindow bWindow = new BWindow();
bWindow.ShowDialog();
}
在 B 窗口中,订阅消息并处理消息:
public BWindow()
{
InitializeComponent();
// 订阅消息
Messenger.Default.Register<SharedValueMessage>(this, OnSharedValueMessageReceived);
}
private void OnSharedValueMessageReceived(SharedValueMessage message)
{
// 使用属性值
UseSharedValue(message.SharedValue);
}
这样,当在 A 窗口中打开 B 窗口时,A 窗口会发送一个消息,消息包含需要共享的属性值,B 窗口订阅了该消息,当消息到达时,B 窗口就会处理消息,并获取到已经传递的属性值。由于消息是在两个窗口之间进行通信的,因此这种方法也可以实现两个窗口之间的数据共享。
方法4:单例类来管理需要共享的属性值
另外一个实现两个窗口之间数据共享的方式是使用一个单例类来管理需要共享的属性值。在 WPF 中,可以使用 Application.Current.Properties 集合来保存全局变量,这个集合中的变量可以在整个应用程序中共享。因此,可以创建一个单例类,将需要共享的属性值保存在 Application.Current.Properties 集合中,然后在 A 和 B 窗口中都访问这个单例类来获取或修改属性值。
具体实现方法如下:
创建一个单例类来管理需要共享的属性值。例如,假设需要共享的属性值为一个字符串类型的变量 SharedValue,则可以这样定义单例类:
public class SharedDataManager
{
private static SharedDataManager instance;
private SharedDataManager()
{
}
public static SharedDataManager Instance
{
get
{
if (instance == null)
{
instance = new SharedDataManager();
}
return instance;
}
}
public string SharedValue
{
get
{
return (string)Application.Current.Properties["SharedValue"];
}
set
{
Application.Current.Properties["SharedValue"] = value;
}
}
}
在 A 窗口打开时,将属性值赋值给单例类:
private void OpenBWindowButton_Click(object sender, RoutedEventArgs e)
{
// 获取属性值
string sharedValue = GetSharedValue();
// 将属性值赋值给单例类
SharedDataManager.Instance.SharedValue = sharedValue;
// 打开 B 窗口
BWindow bWindow = new BWindow();
bWindow.ShowDialog();
}
在 B 窗口中,直接访问单例类来获取属性值:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 获取属性值
string sharedValue = SharedDataManager.Instance.SharedValue;
// 使用属性值
UseSharedValue(sharedValue);
}
这样,当在 A 窗口中打开 B 窗口时,B 窗口就可以访问到已经保存在 Application.Current.Properties 集合中的属性值。由于这个集合中的变量可以在整个应用程序中共享,因此这种方法也可以实现两个窗口之间的数据共享。