【问题标题】:Wpf MainWindow encapsulating multiple Windows - make StartupUri show many windowsWpf MainWindow 封装多个窗口 - 使 StartupUri 显示多个窗口
【发布时间】:2012-03-12 07:38:49
【问题描述】:

目的是创建一个包含多个 WPF 窗口的对象,这些窗口代表一个应该始终一起显示的单元,每个 Window 保留其各自的职责 - 比如说选择在屏幕上布局 X ...

现在因为 WPF 是单窗口架构,我想将此 Windows 列表包装在单个 Window 对象中,以便可以将其设置为例如 StartupUri。

  • 我知道我可以在 Application 启动中手动 Show() 每个 Window,但这不是重点 - 我需要一组粘在一起的窗口,我可以在我的代码库的任何地方轻松调用它们,知道我有一个班级负责联系。
  • 此处对多文档界面 MDI 不感兴趣

我不知道如何实现这样的适配器,我试图覆盖BeginInit,但根本没有被调用。

如何停止窗口初始化

public class MultiWindow : Window
{
    private readonly IList<Window> _windows = new List<Window>();

    public void Register(Window window)
    {
        _windows.Add(window);
    }

    public override void BeginInit()
    {
        foreach (var w in _windows)
            w.Show();
        // base.BeginInit();
    }
}

我不太了解Window 生命周期,有什么办法可以取消初始化并显示已注册窗口的列表吗?

【问题讨论】:

  • 这些 Windows 是在哪里创建的?如果您需要一组保持在一起,您打算如何处理 Window 上的 Close() 事件。功能需求是什么?
  • @BalamBalam 窗口在整个应用程序生命周期中都已注册,并且在我考虑的特定场景中,每当将新显示器连接到计算机时就会创建它们(实际上在移除辅助屏幕时未注册) )。另外,假设有双显示器(所以两个窗口),那么在某些时候窗口可能会被隐藏,然后需要再次一起显示。所以这里的代码并不完全合适,只是为了说明问题。我还没有考虑过如何处理,因为我不确定如何像这样动态地进行分组。
  • 好的,但是“在整个应用程序生命周期中注册”中的“应用程序”是什么?这些 Windows 是在哪里创建的。我们正在谈论 WPF 窗口?页面或对话框呢?
  • @BalamBalam 在这种情况下,负责创建新窗口的工厂是一个检测何时打开更多/新显示的类,这可能在应用程序运行时发生(同样适用于注销; 应用程序在后台/系统托盘中保持活动状态)。例如,当用户单击托盘图标时,应显示所有已注册的窗口。所以问题仍然是关于像这样聚合 Window 对象,而不是 Pages 或任何其他 ui 元素。

标签: c# .net wpf user-interface window


【解决方案1】:

我相信 startupuri 将允许您在应用程序启动时打开一个窗口 如果您想在应用程序启动时打开窗口,您可以这样做。

有App.xaml文件,请到App.xaml.cs文件。

请尝试...关注

  1. 删除 App.xaml 文件中的 StartupUri="MainWindow.xaml"。
  2. 从应用程序继承的应用程序类。您可以重写 OnStartup() 以自定义应用程序启动时间。

        public partial class App : Application
        {
          private readonly IList<Window> _windows = new List<Window>();
    
          protected override void OnStartup(StartupEventArgs e)
          {
            base.OnStartup(e);        
    
            // Add windows you want to open here.
            foreach (var w in _windows)
            {
              w.Show();
            }
        }
    

我不确定这是否是您想要的。我希望这会有所帮助。

【讨论】:

  • 感谢代码,但这不是我想要的,即“我需要一组粘在一起的窗口,我可以在我的代码库的任何地方轻松调用它们,因为我知道我有一个类照顾好联系”
【解决方案2】:

我找到了一种方法,即为普通的单个 Window 对象和实际上包含多个窗口的 Window 对象创建所有窗口的子类 BaseWindow

  • 现在,当您调用 .Show() 时,它会显示一个窗口或多个窗口,具体取决于子类中封装的内容。

所有 Window 对象都应该继承自 BaseWindow

public class BaseWindow : Window
{
    
    // Hide default implementation and call BaseShow instead
    public new void Show()
    {
        BaseShow();
    }

    protected virtual void BaseShow()
    {
        base.Show();
    }

    // ... abstract away any additional Window methods and properties required 
}

覆盖 BaseShow()

public class MultiWindow : BaseWindow
{        
    private readonly IList<Window> _windows = new List<Window>();

    public void Register(Window window)
    {
        _windows.Add(window);
    }

    protected override void BaseShow()
    {
        foreach (var w in _windows)
           w.Show();
    }       
}

在应用启动时设置 MultiWindow

 // First Window object instantiated becomes WPF MainWindow     
 var multiWindow = new MultiWindow();
 multiWindow.Register(new WindowA());
 multiWindow.Register(new WindowB());

使用 MultiWindow,但通过 BaseWindow 调用覆盖的成员

// Cast down to BaseWindow in order to call the overriden member
var baseWindow = (BaseWindow)Application.Current.MainWindow;
// Show WindowA and WindowB
baseWindow.Show();

附注我希望微软在整个 .NET 中使用接口,使用 IWindow 接口而不是具体的 Window 类会提供更多的功能,并且在这种情况下,也易于实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多