T
So, ich habe jetzt mein Userelement soweit überarbeitet und vieles klappt schon so wie es soll.
Allerdings habe ich derzeit noch ein ganz großes Problem:
Wenn ich im Designer ein Element der Liste hinzufüge kommt die Meldung:
Der Konstruktor für den Typ MenuMainItems konnte nicht gefunden werden.
Das Problem ist, ich möchte gerne jedem Menüpunkt eine ID vergeben um später einfacher danach suchen zu können oder damit beim Erstellen gleich als Name "Subitem {1}" erscheint. Um das zu erreichen hat die Klasse den Konstruktor
MenuMainItems(int id);
Im normalen programm würde ich einfach mittels
myList.Add(new MenuMainItems(myList.Count));
die Sache abhaken. Aber der Visual Studio Designer akzeptiert anscheinend nur parameterlose Konstruktoren.
Meine nächste Idee war, die Binding Klasse abzuleiten und die Add-Methode zu überschreiben und dann dort wieder mit
myList.Add(new MenuMainItems(myList.Count));
die Objekte erzeugen. Aber das Klappt auch nicht. Der Visual Studio Designer geht nicht in diese Methode rein. Stattdessen liefert er wieder diese Fehlermeldung beim Debuggen. Wie kann ich das Problem lösen?
Gibt es vielleicht eine Möglichkeit, dem Designer zu verraten wie er neue Elemente in der Liste erzeugen soll? Ich meine es gibt ja die [DefaultBindingProperty] Eigenschaft, aber ich wüsste nicht wie ich das auf einer BindingList<T> mit Parametern anwenden sollte.
Zum Schluss hab ich noch ein letztes Anliegen. Ich möchte gerne das meine Menü-SubItems später ein Klick-Event, nach Außen hin sichtbar, haben. So das ich im jeweiligen Projekt einfach sagen kann, was passieren soll wenn ich auf ein Subitem klicke. Ich habe dazu meiner MenuSubItems-Klasse einen
public delegate void OnClickedHandler(object sender, EventArgs e);
public event OnClickedHandler Clicked;
hinzugefügt. Allerdings sehe ich im Designer nur die Properties und keine Events. Wie muss ich dort vorgehen?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MenuList
{
public enum ButtonState { isActive, isNotActive };
public enum KindOfPanel { MainItem, SubItem};
public partial class MenuList : UserControl
{
//erzeugt Haupt und Untermenüpunkte
//Diese Punkte werden in Form von "MenuPanels", einer
//abgeleiteten Klasse von "Panels()" gespeichert
//Es gibt eine Itemliste, in ihr sind alle MenuMainItems gespeichert
//( public BindingList<MenuMainItems> _items )
//Jedes MenuMainItem hat wiederrum ein Liste mit Subitems
// public BindingList<MenuSubItems> _items
// Jeder dieser Klassen erzeugt Panels mit den jeweiligen gewünschten
// Properties
public BindingList<MenuMainItems> _items = new BindingList<MenuMainItems>();
[System.ComponentModel.DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public BindingList<MenuMainItems> Items { get { return _items;} set{ _items = value;} }
int count;
public MenuList()
{
InitializeComponent();
count = 0;
MenuItems = new List<MenuPanels>();
Items.ListChanged += new ListChangedEventHandler(Items_ListChanged);
Items.AddingNew += new AddingNewEventHandler(Items_AddingNew);
Items.AddNew();
}
private void Items_AddingNew(object sender, AddingNewEventArgs e)
{
e.NewObject = new MenuMainItems(count);
count++;
}
private List<MenuPanels> MenuItems;
public void drawMenu()
{
this.Controls.Clear();
MenuItems.Clear();
foreach (MenuMainItems X in this.Items)
{
MenuItems.Add(getMainMenuItemAsCompletePanel(X));
if (X.MenuPanel.ButtonState == ButtonState.isActive)
{
foreach(MenuSubItems Y in X.SubItems)
{
MenuItems.Add(getSubMenuItemAsCompletePanel(Y));
}
}
}
this.Controls.AddRange(MenuItems.ToArray());
Invalidate();
}
private Point getMenuItemLocation()
{
Point myLoc = new Point(0, 0);
for (int i = 0; i < this.MenuItems.Count; i++)
{
myLoc.Y += MenuItems[i].Size.Height;
}
return myLoc;
}
private MenuPanels getMainMenuItemAsCompletePanel(MenuMainItems item)
{
//System.Windows.Forms.Panel panelMainMenuItem = new Panel();
item.MenuPanel.BackgroundImage = global::MenuList.Properties.Resources.MainMenuButton_Off;
item.MenuPanel.Location = getMenuItemLocation();
item.MenuPanel.Size = new System.Drawing.Size(162, 54);
item.MenuPanel.MouseEnter += new EventHandler(Panel_MouseEnter);
item.MenuPanel.MouseLeave += new EventHandler(Panel_MouseLeave);
item.MenuPanel.Click += new EventHandler(PanelMainMenuItems_Click);
Label myTextOnItem = new Label();
myTextOnItem.Text = item.Text;
myTextOnItem.ForeColor = Color.White;
myTextOnItem.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
myTextOnItem.Location = new Point(0, 0);
myTextOnItem.BackColor = Color.Transparent;
item.MenuPanel.Controls.Add(myTextOnItem);
return item.MenuPanel;
}
private void PanelMainMenuItems_Click(object sender, EventArgs e)
{
MenuPanels myPanel = (MenuPanels)sender;
if (myPanel.ButtonState == ButtonState.isActive)
{
myPanel.ButtonState = ButtonState.isNotActive;
}
else
{
myPanel.ButtonState = ButtonState.isActive;
}
this.drawMenu();
}
private void Panel_MouseEnter(object sender, EventArgs e)
{
MenuPanels myPanel = (MenuPanels)sender;
if (myPanel.KindOfPanel == KindOfPanel.MainItem)
{
myPanel.BackgroundImage = global::MenuList.Properties.Resources.MainMenuButton_On;
}
else
{
myPanel.BackgroundImage = global::MenuList.Properties.Resources.subitem_on;
}
}
private void Panel_MouseLeave(object sender, EventArgs e)
{
MenuPanels myPanel = (MenuPanels)sender;
if (myPanel.KindOfPanel == KindOfPanel.MainItem)
{
myPanel.BackgroundImage = global::MenuList.Properties.Resources.MainMenuButton_Off;
}
else
{
myPanel.BackgroundImage = global::MenuList.Properties.Resources.subitem_off;
}
}
private MenuPanels getSubMenuItemAsCompletePanel(MenuSubItems Item)
{
Item.MenuPanel.BackgroundImage = global::MenuList.Properties.Resources.subitem_off;
Item.MenuPanel.Location = getMenuItemLocation();
Item.MenuPanel.Size = new System.Drawing.Size(162, 33);
Item.MenuPanel.MouseEnter += new EventHandler(Panel_MouseEnter);
Item.MenuPanel.MouseLeave += new EventHandler(Panel_MouseLeave);
Label myTextOnItem = new Label();
myTextOnItem.Text = Item.Text;
myTextOnItem.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
myTextOnItem.Location = new Point(20, 10);
myTextOnItem.ForeColor = Color.Black;
myTextOnItem.BackColor = Color.Transparent;
Item.MenuPanel.Controls.Add(myTextOnItem);
return Item.MenuPanel;
}
private void Items_ListChanged(object sender, ListChangedEventArgs e)
{
drawMenu();
}
}
[Serializable]
public class MenuMainItems
{
private MenuPanels _panel;
public MenuMainItems(int id) //: this(
{
_panel = new MenuPanels(KindOfPanel.MainItem,id);
_name = string.Format("Hauptitem {0}", id);
_text = string.Format("HauptitemText {0}", id);
}
public BindingList<MenuSubItems> _items = new BindingList<MenuSubItems>();
private string _name;
private string _text;
public BindingList<MenuSubItems> SubItems
{
get
{
return _items;
}
set
{
_items = value;
}
}
public string Name { get { return _name; } set { _name = value; } }
public string Text { get { return _text; } set { _text = value; } }
public MenuPanels MenuPanel { get { return _panel; } }//set { _panel = value; } }
}
[Serializable]
public class MenuSubItems
{
private MenuPanels _panel;
MenuSubItems(int id)
{
_panel = new MenuPanels(KindOfPanel.SubItem,id);
_panel.Click += new EventHandler(OnClicked);
}
private string _name;
private string _text;
public delegate void OnClickedHandler(object sender, EventArgs e);
public event OnClickedHandler Clicked;
protected virtual void OnClicked(object sender, EventArgs e)
{
if (Clicked != null)
{
Clicked(sender,e); // Notify Subscribers
}
}
public string Name { get { return _name; } set { _name = value; } }
public string Text { get { return _text; } set { _text = value; } }
public MenuPanels MenuPanel { get { return _panel; } }//set { _panel = value; } }
}
[Serializable]
public class MenuPanels : Panel
{
int _panelID;
public MenuPanels(KindOfPanel kind, int id)
{
_panelID = id;
_kind = kind;
_state = global::MenuList.ButtonState.isNotActive;
}
private ButtonState _state;
private KindOfPanel _kind;
public KindOfPanel KindOfPanel { get { return _kind; } set { _kind = value; } }
public ButtonState ButtonState
{
get { return _state; }
set { _state = value; }
}
public int PanelID
{
get { return _panelID; }
}
}
}