2

以下是我的代码。

public class baseMenuItem : MenuItem
{        
    public baseMenuItem()
    {
        this.Click += baseMenuItem_Click;
    }

    void baseMenuItem_Click(object sender, RoutedEventArgs e)
    {
        //When user click the menu, I will need to new a window which type is assigned from AssignHandleWindow<T>()
    }

    public void AssignHandleWindow<T>() where T : baseWindow 
    {
        //Can I save <T> into somewhere for later Click-event using?
        //How do I do that?
    }
}

我不确定这是否可行,但我的应用程序中可能还有 40 个 menuItems,我不想为每个人写点击事件来打开窗口,知道吗?

谢谢。

4

4 回答 4

1

反射在这里可能是一个更好的选择。您可以通过控件上的 Tag 属性将自定义数据与控件相关联 ( http://msdn.microsoft.com/en-us/library/system.windows.forms.control.tag%28v=vs.110%29。 .aspx)。您可以将要打开的窗口的完全限定类型名称分配给标记(通过设计器或通过代码)。通过代码,它看起来像这样:

menuItem.Tag = "namespace.class, dllname";

然后在通用事件处理程序中执行以下操作(我的 Win Forms 有点生疏,但它应该让您知道需要做什么):

void baseMenuItem_Click(object sender, RoutedEventArgs e)
{
    Control senderAsControl = (Control)sender;
    Type windowType = Type.GetType((string)(senderAsControl.Tag));
    Control window = (Control)Activator.CreateInstance(windowType);
    window.Show();
}

完全未经测试的通常序言适用。

于 2013-11-13T05:26:53.080 回答
1

您可以在字段中保存类型,然后使用

public class baseMenuItem : MenuItem
{        
    Type windowType;
    public baseMenuItem()
    {
        this.Click += baseMenuItem_Click;
    }

    void baseMenuItem_Click(object sender, RoutedEventArgs e)
    {
        if(windowType != null){
            window = (Control)Activator.CreateInstance(windowType);
            window.Show();
        }
    }

    public void AssignHandleWindow<T>() where T : baseWindow 
    {
        windowType = typeof(T);
    }
}
于 2013-11-13T05:41:48.910 回答
0
public T AssignHandleWindow<T>() where T : baseWindow, new() 
{
    var window = new T();
    return window;
}

以上能行吗?

然后,您可以从单击处理程序中调用它。

于 2013-11-13T05:32:32.860 回答
0

我最近填充了一个下拉菜单

var thingsForMenu = getThingsForMenuBasedOnWhasClickedOn();
foreach(var v in thingsForMenu) {
    ToolStripItem ti = new ToolStripMenuItem(v.key);
    var localItem c = v.value;
    ti.onClick += (o,ie) => {
         doTheThing(c);
    }
    ToolStrip.DropDownItems.Add(ti);
}

注意:c 的局部变量副本很关键,因为 v 在循环内被重新分配,并且您需要传递一个指向 c in 的指针,而不仅仅是函数返回后恰好存在于内存中的 v.value(通常会导致在所有菜单项中调用相同的东西)

这不是您问题的“我如何使用泛型”答案,但确实提供了一种将信息传达给 onClick 处理程序的机制。

于 2013-11-13T05:41:27.953 回答