2013-11-13 4 views
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 в моем приложении, я не хочу писать для каждого из них нажмите событие, чтобы открыть окно, любую идею?

Спасибо.

+0

вы можете предоставить образец, как она должна работать? – Grundy

+0

'Когда пользователь нажимает меню, мне нужно будет создать новое окно, что означает, что вы уже знаете, какое окно показывать. Итак, похоже на проблему наследования. – Muctadir

ответ

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); 
    } 
} 
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(); 
} 

Обычная преамбула этого полностью непроверенного применения.

+0

Это тоже отличное решение, я пробовал, и он работает, я действительно хочу отметить его как ответ, однако этот сайт, похоже, не позволяет мне это делать (отметьте 2 ответа), спасибо. – Fishman

0
public T AssignHandleWindow<T>() where T : baseWindow, new() 
{ 
    var window = new T(); 
    return window; 
} 

Может ли вышеуказанная работа?

Затем вы можете вызвать это из обработчика кликов.

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); 
} 

примечания: локальная переменная копия с имеет решающее значение, так как v повторно назначена внутри цикла, и вам нужно передать указатель на с в , а не только в зависимости от того, какое значение v.value сохраняется в памяти после возвращения функции (как правило, приводит к тому, что все пункты меню вызывают одно и то же)

Это не совсем «как я могу использовать генерики» ответ на ваш вопрос, но обеспечивает механизм для передачи информации в обработчик onClick.

Смежные вопросы