【问题标题】:Initializing a WPF-window with an optional parameter使用可选参数初始化 WPF 窗口
【发布时间】:2014-10-08 12:41:38
【问题描述】:

我有两个窗口。主窗口和自动导入。主要目标是在窗口之间切换,同时保持一个窗口处于活动状态而不是关闭它。我希望一个显示而另一个隐藏。我可以通过使用一个窗口作为另一个窗口的参数来做到这一点。我遇到的唯一问题是启动窗口是带有参数的窗口。我猜这需要是可选的吗?我不确定您将如何使用 Window 来执行此操作。

当我的项目开始时,主窗口出现。代码是

public partial class MainWindow : Window
{
    private AutoImport auto;

    public MainWindow(AutoImport parent)
    {
        InitializeComponent();
        auto = parent;
    }

    public void btnAutoImport_Click(object sender, RoutedEventArgs e)
    {
        this.Hide();
        auto.Show();   
    }
}

如果我点击按钮,主窗口应该隐藏,另一个窗口应该出现。代码是

public AutoImport()
{
    InitializeComponent();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    this.Hide();
    MainWindow main = new MainWindow(this);
    main.Show();           
}

然后可以对 AutoImport 进行更改,当单击此表单上的按钮时,AutoImport 将隐藏并且会出现一个新的 MainWindow。如果再次单击主窗口上的按钮,AutoImport 会显示之前所做的更改。当我在表单上切换代码时,这样做没有问题。

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    要执行您的要求,您只需向 MainWindow 添加另一个构造函数:

    public partial class MainWindow : Window
    {
        private AutoImport auto;
    
        public MainWindow()
        {
            InitializeComponent();
        }
    
        public MainWindow(AutoImport parent)
        {
            InitializeComponent();
            auto = parent;
        }
    
        public void btnAutoImport_Click(object sender, RoutedEventArgs e)
        {
            this.Hide();
            if (auto == null) { auto = new AutoImport(); }
            auto.Show();   
        }
    }
    

    虽然我认为在 AutoImport 中保留该 MainWindow 实例的副本可能更有意义,因为您只是隐藏它。因此,当您创建 MainWindow 的实例时,您还创建了 AutoImport 的实例,将 MainWindow 设置为 AutoImport 的属性/字段。然后,当您单击按钮时,窗口将被交换。这样您就不必每次都创建一个新的 MainWindow。像这样的:

    public partial class MainWindow : Window
    {
        private AutoImport auto;
    
        public MainWindow()
        {
            InitializeComponent();
        }
    
        public MainWindow_Loaded(object sender, EventArgs e)
        {
            auto = new AutoImport(this);
        }
    
        public void btnAutoImport_Click(object sender, RoutedEventArgs e)
        {
            this.Hide();
            auto.Show();   
        }
    }
    
    public class AutoImport
    {
        private Window LinkedWindow { get; set; }
        public AutoImport(Window parent)
        {
            InitializeComponent();
            LinkedWindow = parent;
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.Hide();
            LinkedWindow.Show();           
        }
    }
    

    【讨论】:

      【解决方案2】:

      就非默认构造函数而言......

      除了默认的构造函数,添加这个:

      public MainWindow(AutoImport parent) : this()
      {
          auto = parent;
      }
      

      : this() 将确保默认构造函数运行,其中包含InitializeComponent(),这样您就不会重复代码。

      关于您的设计方法的主题,如果您不采用 MVVM 路线(似乎是这种情况),我将创建某种窗口管理器类来处理内存中的哪些窗口及其状态。通过对两个窗口进行双向控制来控制谁在显示和谁在隐藏,您正在创建非常紧密的耦合,并且任何更改都将是大量工作。我说让第三方(另一个班级)处理这类事情。为什么一个窗口应该知道另一个窗口的存在呢?如果一个经理在处理所有的工作或传递数据,而另一个经理在处理状态,那么窗口本身只需要关心他们在做什么。想想他们的职责......他们应该知道什么以及他们应该能够做什么......当然不是另一个窗口的状态(在我看来)。

      请注意,我不知道您的应用程序的全部范围,所以也许您的解决方案可以很好地解决它而无需过度设计。我有一个案例,我需要一个非常基本的设置,所以我只是为每个窗口添加了一个静态属性。我让该属性在创建后保存窗口的实例(在构造函数中完成)。如果在我尝试检查属性时没有实例化任何实例,则说明该属性创建了一个实例。基本上,单例实现。因此,每当另一个窗口需要访问某个窗口时,它所要做的就是调用SomeWindow.Instance.Show(),该窗口就会出现。如果没有先前的实例,则会创建并显示一个。我允许该属性处理所有关于知道窗口是否已经在内存中的脏活。这也让我可以访问他们的数据。非常骇人听闻的方式,但它非常适合这种简单的场景。

      这就是编程的美妙之处——问题可以用无限的方式解决。

      【讨论】:

        猜你喜欢
        • 2019-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多