You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xamarin macOS C#应用中复制主窗口?

解决Xamarin macOS复制主窗口的问题

问题核心原因

你的两种实现方式失败主要源于两个关键点:

  1. 故事板名称或标识符配置不匹配
  2. 未持有窗口控制器的强引用,导致其被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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 04:31:09