WPF点击按钮弹出一个窗口
一、基本方法:直接实例化并显示窗口
1. 普通窗口(无参数)
- 适用场景:简单的弹出窗口,无需传递数据。
private void Button_Click(object sender, RoutedEventArgs e)
{
var newWindow = new MyWindow(); // 实例化新窗口
newWindow.Show(); // 非模态显示(用户可继续操作原窗口)
// 或 newWindow.ShowDialog(); // 模态显示(阻塞原窗口,直到新窗口关闭)
}
- 非模态窗口(
Show()
):用户可同时操作原窗口和新窗口。 - 模态窗口(
ShowDialog()
):强制用户先关闭新窗口,才能操作原窗口。
二、传递数据到新窗口
1. 通过构造函数传递
- 适用场景:新窗口需要初始化数据(如用户ID、标题等)。
// 新窗口的构造函数
public MyWindow(string title)
{
InitializeComponent();
this.Title = title; // 设置窗口标题
}
// 按钮点击事件
private void Button_Click(object sender, RoutedEventArgs e)
{
var newWindow = new MyWindow("Custom Title");
newWindow.Show();
}
通过公共属性传递
- 适用场景:需要在新窗口打开后动态更新数据。
// 新窗口的公共属性
public string Data { get; set; }
// 按钮点击事件
private void Button_Click(object sender, RoutedEventArgs e)
{
var newWindow = new MyWindow();
newWindow.Data = "Hello from Main Window"; // 设置数据
newWindow.Show();
}
三、返回数据到原窗口
1. 模态窗口 + 返回值
- 适用场景:新窗口需要返回用户输入(如对话框的确认/取消)。
// 新窗口(模态)
public partial class InputWindow : Window
{
public string UserInput { get; private set; }
private void Button_OK_Click(object sender, RoutedEventArgs e)
{
UserInput = txtInput.Text; // 获取用户输入
this.DialogResult = true; // 设置对话框结果
this.Close();
}
}
// 原窗口调用
private void Button_Click(object sender, RoutedEventArgs e)
{
var inputWindow = new InputWindow();
if (inputWindow.ShowDialog() == true) // 检查DialogResult
{
MessageBox.Show($"You entered: {inputWindow.UserInput}");
}
}
2. 事件回调(非模态窗口)
- 适用场景:非模态窗口需要通知原窗口数据变化。
// 新窗口定义事件
public event Action<string> DataChanged;
private void Button_Send_Click(object sender, RoutedEventArgs e)
{
DataChanged?.Invoke(txtInput.Text); // 触发事件
}
// 原窗口订阅事件
private void Button_Click(object sender, RoutedEventArgs e)
{
var newWindow = new MyWindow();
newWindow.DataChanged += (data) =>
{
MessageBox.Show($"Received: {data}");
};
newWindow.Show();
}
四、高级模式:MVVM与数据绑定
1. 使用ViewModel共享数据
// 共享的ViewModel
public class SharedViewModel : INotifyPropertyChanged
{
private string _sharedData;
public string SharedData
{
get => _sharedData;
set { _sharedData = value; OnPropertyChanged(); }
}
// 实现INotifyPropertyChanged...
}
// 原窗口(设置ViewModel)
public partial class MainWindow : Window
{
public SharedViewModel ViewModel { get; } = new SharedViewModel();
private void Button_Click(object sender, RoutedEventArgs e)
{
var newWindow = new MyWindow { DataContext = ViewModel }; // 共享ViewModel
newWindow.Show();
}
}
// 新窗口(绑定到ViewModel)
public partial class MyWindow : Window
{
public MyWindow()
{
InitializeComponent();
this.DataContextChanged += (s, e) =>
{
var vm = DataContext as SharedViewModel;
if (vm != null) vm.SharedData = "New Data from Child Window";
};
}
}
对话框
//注册对话框(卖出策略模块)
containerRegistry.RegisterDialog<SellView, SelViewModel>();
public ObservableCollection<SellModel> Items
{
get;
set;
} = new ObservableCollection<SellModel>();public MainWindowViewModel(IUnityContainer container, IRegionManager regionManager, IStrategyService strategyService, IDialogService dialogService)
{
_dialogService = dialogService;
}//按钮按下显示弹窗
private void Button_Click()
{
//传递参数
var parameters = new DialogParameters
{
{ "DataList", Items }
};_dialogService.ShowDialog("SellView", parameters, (IDialogResult result) =>
{
// 从结果中获取数据链表
if (result.Parameters.TryGetValue<ObservableCollection<SellModel>>("DataList", out var dataList))
{
Items = dataList;
}
});}
//弹窗
class SellViewModel : BindableBase, IDialogAware
{public SellStrategyViewModel(IContainerExtension container, IRegionManager regionManager)
{
_container = container;
_regionManager = regionManager;
}
/// <summary>
/// 允许关闭对话框
/// </summary>
/// <returns></returns>
public bool CanCloseDialog()
{
return true;
}/// <summary>
/// 关闭对话框时
/// </summary>
public void OnDialogClosed()
{
var resultParameters = new DialogParameters
{
{ "DataList", Items }
};
// 触发请求关闭事件
RequestClosed?.Invoke(resultParameters);
}/// <summary>
/// 打开对话框时
/// </summary>
/// <param name="parameters"></param>
public void OnDialogOpened(IDialogParameters parameters)
{
if (parameters.TryGetValue<ObservableCollection<SellModel>>("DataList", out var initialName))
{
Items = initialName;
}
}}