【问题标题】:Passing Window/Type as Parameter将窗口/类型作为参数传递
【发布时间】:2012-06-28 13:27:18
【问题描述】:

我的代码并不是那么相关,只是为了给你背景,我有一个方法可以像这样打开一个窗口 messageWindow 的实例;

private void SetMessagePosition(Controls.Button btn, string text)
        {
            messageWindow = new messageWindow(text);
            relativePoint = btn.TransformToAncestor(this).Transform(new Point(0, 0));

            messageWindow.Left = relativePoint.X + this.Left;
            messageWindow.Top = relativePoint.Y + this.Top;
            messageWindow.Show();
        }

但是我想看看我是否可以使用这种方法打开其他窗口。这显然意味着将我要打开的新窗口的名称作为参数传递给它。我的问题是,怎么做?我试过像这样传递参数;

private void SetMessagePosition(Window newWin, Controls.Button btn, string text))
        {
            newWin = new newWin(text);
            ...

其中newWin = 我要打开的窗口类型。但显然new newWin 部分会引发错误,因为VS 不知道名为newWin 的窗口。

我知道你的第一个想法可能是,为什么不在调用这个方法之前实例化窗口,然后我可以一起跳过这行。好吧,这个方法实际上是在打开时设置新窗口相对于父窗口的位置,所以,我之前不能设置它的位置。

我想尝试的另一件事是;

List<Window> winList;
List<Type> winListType;

winList.Add(window1);
winList.Add(window2);
winList.Add(window3);

winListType.Add(Window1);
winListType.Add(Window2);
winListType.Add(Window3);

SetMessagePosition(winList[2], winListType[2], btn1, "Yes");

private void SetMessagePosition(Window newWin, Type newWinType, Controls.Button btn, string text))
        {
            newWin = new newWinType(text);
            ...

newWinType 不喜欢传递Type 而不是变量,即使它是Type 的列表。如果有人知道这样做的方法/解决方法,我会印象深刻。

【问题讨论】:

  • 为了更灵活,我建议使用界面而不是窗口和类型
  • @HichemC 抱歉,但我对接口一无所知。现在将阅读它们。

标签: c# wpf parameters window


【解决方案1】:

你需要把它变成一个泛型方法,这样你才能传递类型:

private void SetMessagePosition<T>(Controls.Button btn, string text) where T : Window, new()
{
    T window = new T();
    relativePoint = btn.TransformToAncestor(this).Transform(new Point(0, 0));
    window.Left = relativePoint.X + this.Left;
    window.Top = relativePoint.Y + this.Top;
    window.Show();
}

那么,你可以这样称呼它:

SetMessagePosition<messageWindow>(btn, text);

但是,这种方法的缺点是,当您通过泛型类型实例化对象时,您无法将任何内容传递给构造函数。因此,您需要以不同的方式在窗口上设置文本,例如创建一个具有 SetText 方法或类似方法的界面,并且可以将其添加为泛型类型的另一个约束。

您可以通过简单地期望新窗口已经被实例化并传递给方法而不是让方法自己实例化它来简化整个混乱:

private void SetMessagePosition(Window window, Controls.Button btn)
{
    relativePoint = btn.TransformToAncestor(this).Transform(new Point(0, 0));
    window.Left = relativePoint.X + this.Left;
    window.Top = relativePoint.Y + this.Top;
    window.Show();
}

那么,你可以这样称呼它:

SetMessagePosition(new newWin(text), btn);

【讨论】:

  • 所以我使用的是上面的内容,但它指向我的初始化程序行和错误“无法创建变量类型 'T' 的实例,因为它没有 new() 约束”。有什么想法吗?
  • 我想知道它是否与stackoverflow.com/questions/980629/…有关
  • 我通过添加new() 约束来修复我的示例,以便强制类型T 能够使用new 关键字和无参数构造函数进行实例化。不幸的是,您的窗口在其构造函数中获取文本,因此必须以不同的方式完成。
  • 哦,所以没有传递参数? :/ 这很烦人。
  • 啊!在方法调用中实例化它们,不知道我能做到这一点。也简单多了。谢谢:D
【解决方案2】:

通过使用这样的界面:

interface IWindow
    {
        int Left
        {
            get;
            set;
        }
        int Right
        {
            get;
            set;
        }
    void ShowWindow();
}

然后在所有窗口中实现它,无论它是什么类型。

 public partial class MainWindow : Window , IWindow
    {
        public MainWindow()
        {
            InitializeComponent();

        }



        public new int Left
        {
            get
            {
                return Left;
            }
            set
            {
                Left = value;
            }
        }

        public int Right
        {
            get
            {
                return Right;
            }
            set
            {
                Left = value;
            }
        }

        public void ShowWindow()
        {
            Show();
        }
    }

然后将参数更改为IWindow,如下所示:

private void SetMessagePosition(IWindow window, Controls.Button btn, string text))
        {

【讨论】:

  • 但是 IWindow 与 XAML 有什么关系呢?
  • 按窗口属性需要更改。
  • 我必须用 C# 进行设计吗?我已经在 XAML 中完成了很多工作。
  • 这个选项本来可以的,只是我对接口不够了解。不过肯定会更多地研究它们。 +1 谢谢!
  • 我真的建议你这样做,尽管 SteveDog 使用泛型的回答非常简单有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 2015-03-22
  • 2021-02-12
  • 1970-01-01
相关资源
最近更新 更多