如何在Xamarin macOS C#应用中复制主窗口?
解决Xamarin macOS复制主窗口的问题
问题核心原因
你的两种实现方式失败主要源于两个关键点:
- 故事板名称或标识符配置不匹配
- 未持有窗口控制器的强引用,导致其被GC回收,窗口刚创建就消失
正确实现步骤
第一步:确认故事板配置
打开Main.storyboard,选中主窗口控制器(MainWindowController),在右侧Identity Inspector(快捷键⌘+⌥+3)中:
- 设置
Storyboard ID为MainWindowController(自定义名称也可以,但必须和代码里的标识符一致) - 确保窗口控制器的
Class绑定到你的MainWindowController类
第二步:从故事板实例化窗口的正确代码
// 获取主故事板,默认文件名是Main.storyboard,因此名称传"Main" var storyboard = NSStoryboard.FromName("Main", null); // 实例化窗口控制器,标识符需和故事板中设置的完全一致 var windowController = storyboard.InstantiateControllerWithIdentifier("MainWindowController") as NSWindowController; // 空引用判断,避免异常 if (windowController?.Window != null) { // 显示并激活新窗口 windowController.Window.MakeKeyAndOrderFront(this); // 关键操作:持有强引用,防止GC回收窗口控制器 // 建议在AppDelegate或全局类中维护一个列表保存所有窗口控制器 // 例如在AppDelegate中添加:private List<NSWindowController> _openWindows = new List<NSWindowController>(); _openWindows.Add(windowController); }
原有代码失败的具体原因
- 第一种方式:直接
new MainWindowController()无法加载故事板中的窗口布局和视图元素——绑定故事板的控制器必须通过故事板实例化,才能关联到预设的界面结构。 - 第二种方式:故事板名称错误(默认主故事板是
Main而非main_storyboard),且缺少强引用,窗口控制器被GC回收后窗口直接消失。
额外提示(复制窗口内容状态)
如果需要新窗口完全继承原窗口的实时数据状态,实例化后需手动传递数据:
if (windowController?.Window?.ContentViewController is MainViewController newVc) { // 假设原窗口的视图控制器是MainViewController var originalVc = (MainViewController)NSApplication.SharedApplication.MainWindow.ContentViewController; // 复制数据并更新新窗口UI newVc.CurrentData = originalVc.CurrentData; newVc.RefreshUI(); }
内容的提问来源于stack exchange,提问作者Aw Man3703
相关产品推荐
相关产品推荐

