我在做一个menubar ,menu 中的结构为这样的
Menu 1
Sub men 1
Sub men 2
Menu 2
Sub men 1
Sub men 2
我现在想将 Menu 中的所有菜单存放在一个 XML 中
<?xml version="1.0" encoding="gb2312"?>
<root>
<Main_Menu>
<Main_Menu_Item Menu_Title="Menu 1" PointObject="men1">
<Item Menu_Title=" Sub men 1" PointObject=" Submen1" />
<Item Menu_Title=" Sub men 2" PointObject=" Submen2" />
</Main_Menu_Item>
<Main_Menu_Item Menu_Title="Menu 2" PointObject="men2">
<Item Menu_Title=" Sub men 1" PointObject=" Submen1" />
<Item Menu_Title=" Sub men 2" PointObject=" Submen2" />
</Main_Menu_Item>
</Main_Menu>
</root>
Menu_Title 为菜单所显示的标题, PointObject 为 对应 win form 的名称 eg : Submen1.cs 的PointObject 为 "Submen1"
现在的问题是: 当用户点击 "Menu 1" 下面的 "Sub men 1" 时如何根据 "Submen1" 这个名词来调用 Submen1.cs
同时在显示Submen1 winform时制 同一个用户只能打开一次
16 个解决方案
#1
看标题应该用反射~~
但看楼主描述,似乎应该使用FindControl
但看楼主描述,似乎应该使用FindControl
#2
这段是自动生成菜单,并为每个菜单项生成事件的代码,是在vs2005里面写的,vs2003也是大同小异,里面的菜单名加载是引用资源里的文件,换成xml文件就行了。
public static void AddSkinMenu(ToolStripMenuItem toolMenu)
{
DataSet skin = new DataSet();
try
{
skin.ReadXml("skin.xml",XmlReadMode.Auto);
}
catch
{
}
if (skin==null||skin.Tables.Count < 1)
{
skin = new DataSet();
skin.Tables.Add("skin");
skin.Tables["skin"].Columns.Add("style");
System.Data.DataRow dr = skin.Tables["skin"].NewRow();
dr[0] = "系统默认";
skin.Tables[0].Rows.Add(dr);
skin.WriteXml("skin.xml", XmlWriteMode.IgnoreSchema);
}
foreach (SkinType st in (SkinType[])System.Enum.GetValues(typeof(SkinType)))
{
toolMenu.DropDownItems.Add(new ToolStripMenuItem(st.ToString()));
toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1].Click += new EventHandler(frm_Main_Click);
if (st.ToString() == skin.Tables[0].Rows[0][0].ToString())
{
((ToolStripMenuItem)toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1]).Checked = true;
frm_Main_Click(toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1], null);
}
}
toolMenu.DropDownItems.Add(new ToolStripMenuItem("系统默认"));
toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1].Click += new EventHandler(frm_Main_Click);
if (skin.Tables[0].Rows[0][0].ToString() == "系统默认")
{
((ToolStripMenuItem)toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1]).Checked = true;
}
}
public static void AddSkinMenu(ToolStripMenuItem toolMenu)
{
DataSet skin = new DataSet();
try
{
skin.ReadXml("skin.xml",XmlReadMode.Auto);
}
catch
{
}
if (skin==null||skin.Tables.Count < 1)
{
skin = new DataSet();
skin.Tables.Add("skin");
skin.Tables["skin"].Columns.Add("style");
System.Data.DataRow dr = skin.Tables["skin"].NewRow();
dr[0] = "系统默认";
skin.Tables[0].Rows.Add(dr);
skin.WriteXml("skin.xml", XmlWriteMode.IgnoreSchema);
}
foreach (SkinType st in (SkinType[])System.Enum.GetValues(typeof(SkinType)))
{
toolMenu.DropDownItems.Add(new ToolStripMenuItem(st.ToString()));
toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1].Click += new EventHandler(frm_Main_Click);
if (st.ToString() == skin.Tables[0].Rows[0][0].ToString())
{
((ToolStripMenuItem)toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1]).Checked = true;
frm_Main_Click(toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1], null);
}
}
toolMenu.DropDownItems.Add(new ToolStripMenuItem("系统默认"));
toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1].Click += new EventHandler(frm_Main_Click);
if (skin.Tables[0].Rows[0][0].ToString() == "系统默认")
{
((ToolStripMenuItem)toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1]).Checked = true;
}
}
#3
to: Sharp Shooter
findcontrol 是行不通的,因为查找的对象不是个 control 而是一个尚未实例化的 对象引用
to: alldj(灵山妖姬)
你的方法是可行的但,不是我想要的,我现在关问题是 能否通对 Winform 的名称来实例化该对
象
望朋友帮忙
findcontrol 是行不通的,因为查找的对象不是个 control 而是一个尚未实例化的 对象引用
to: alldj(灵山妖姬)
你的方法是可行的但,不是我想要的,我现在关问题是 能否通对 Winform 的名称来实例化该对
象
望朋友帮忙
#4
用反射做
先把submen.cs编译成.dll放在bin里
然后加载。
Assembly a = Assembly.Load("namespace.submen1.dll");
(Form)Activator.CreateInstance(a.GetTypes()).ShowDialog();
先把submen.cs编译成.dll放在bin里
然后加载。
Assembly a = Assembly.Load("namespace.submen1.dll");
(Form)Activator.CreateInstance(a.GetTypes()).ShowDialog();
#5
反射是可以,但是可能有些损耗性能
其实这种问题如果有个统一的命名规则的话、
直接findcontrol
或者将control和xml title 弄一个dictionary 调用
应该是个不错的解决方案
毕竟这样没有反射损耗性能
其实这种问题如果有个统一的命名规则的话、
直接findcontrol
或者将control和xml title 弄一个dictionary 调用
应该是个不错的解决方案
毕竟这样没有反射损耗性能
#6
如果你要调用的类直接就和主窗口在一个项目里的话,用
Assembly a = Assembly.GetExecutingAssembly()就可以获得当前的Assembly
然后Type t = a.GetType(类名)获得类(最好是带namespace的全名)
最后Activator.CreateInstance(t)即可,谨慎起见最好这三句套个try作意外处理
Assembly a = Assembly.GetExecutingAssembly()就可以获得当前的Assembly
然后Type t = a.GetType(类名)获得类(最好是带namespace的全名)
最后Activator.CreateInstance(t)即可,谨慎起见最好这三句套个try作意外处理
#7
测试中,谢谢大家的热心帮忙,测试完结贴,顶者有分
#8
private void button1_Click(object sender, EventArgs e)
{
string frm = "Form2";
for (int i = 0; i < Application.OpenForms.Count; i++)
{
if (Application.OpenForms[i].Name == frm)
{
return;
}
}
System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
//object obj=thisDll.CreateInstance("Form2");
Type typForm = ass.GetType( "testDLL."+frm );
if( typForm == null ) return;
Form frmTest = typForm.InvokeMember( null,BindingFlags.DeclaredOnly |BindingFlags.Public | BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.CreateInstance,null,null,null ) as Form;
if( frmTest == null ) return;
else
{
frmTest.Name=frm;
frmTest.Show();
}
}
{
string frm = "Form2";
for (int i = 0; i < Application.OpenForms.Count; i++)
{
if (Application.OpenForms[i].Name == frm)
{
return;
}
}
System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
//object obj=thisDll.CreateInstance("Form2");
Type typForm = ass.GetType( "testDLL."+frm );
if( typForm == null ) return;
Form frmTest = typForm.InvokeMember( null,BindingFlags.DeclaredOnly |BindingFlags.Public | BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.CreateInstance,null,null,null ) as Form;
if( frmTest == null ) return;
else
{
frmTest.Name=frm;
frmTest.Show();
}
}
#9
可用类工厂
#10
不行,我在Vs2003中不能用OpenForms的属性
#11
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindowEx")] //找子窗体
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll", EntryPoint = "SendMessage")] //用于发送信息给窗体
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
/// <summary>
/// 查找是否已创建窗体
/// </summary>
/// <param name="FormTitle">标题名称</param>
/// <returns></returns>
public static bool SearchForm(string FormTitle)
{
IntPtr ParenthWnd = new IntPtr(0);
IntPtr EdithWnd = new IntPtr(0);
//查到窗体,得到整个窗体
ParenthWnd = FindWindow(null,FormTitle);
if (!ParenthWnd.Equals(IntPtr.Zero))
{
return true;
}
else
{
return false;
}
}
private void button1_Click(object sender, EventArgs e)
{
string frm = "FormTitle";
if (SearchForm(frm))
{
return;
}
frm="Form2";
System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
//object obj=thisDll.CreateInstance("Form2");
Type typForm = ass.GetType( "testDLL."+frm );
if( typForm == null ) return;
Form frmTest = typForm.InvokeMember( null,BindingFlags.DeclaredOnly |BindingFlags.Public | BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.CreateInstance,null,null,null ) as Form;
if( frmTest == null ) return;
else
{
frmTest.Name=frm;
frmTest.Show();
}
}
#12
.net 反射机制
#13
to :alldj(灵山妖姬)
找不到BindingFlags
找不到BindingFlags
#14
学习
#15
System.Reflection.BindingFlags 可以,测试中
#16
可以了,谢谢大家
to :alldj(灵山妖姬)
你的方法可行
to :alldj(灵山妖姬)
你的方法可行
#1
看标题应该用反射~~
但看楼主描述,似乎应该使用FindControl
但看楼主描述,似乎应该使用FindControl
#2
这段是自动生成菜单,并为每个菜单项生成事件的代码,是在vs2005里面写的,vs2003也是大同小异,里面的菜单名加载是引用资源里的文件,换成xml文件就行了。
public static void AddSkinMenu(ToolStripMenuItem toolMenu)
{
DataSet skin = new DataSet();
try
{
skin.ReadXml("skin.xml",XmlReadMode.Auto);
}
catch
{
}
if (skin==null||skin.Tables.Count < 1)
{
skin = new DataSet();
skin.Tables.Add("skin");
skin.Tables["skin"].Columns.Add("style");
System.Data.DataRow dr = skin.Tables["skin"].NewRow();
dr[0] = "系统默认";
skin.Tables[0].Rows.Add(dr);
skin.WriteXml("skin.xml", XmlWriteMode.IgnoreSchema);
}
foreach (SkinType st in (SkinType[])System.Enum.GetValues(typeof(SkinType)))
{
toolMenu.DropDownItems.Add(new ToolStripMenuItem(st.ToString()));
toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1].Click += new EventHandler(frm_Main_Click);
if (st.ToString() == skin.Tables[0].Rows[0][0].ToString())
{
((ToolStripMenuItem)toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1]).Checked = true;
frm_Main_Click(toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1], null);
}
}
toolMenu.DropDownItems.Add(new ToolStripMenuItem("系统默认"));
toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1].Click += new EventHandler(frm_Main_Click);
if (skin.Tables[0].Rows[0][0].ToString() == "系统默认")
{
((ToolStripMenuItem)toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1]).Checked = true;
}
}
public static void AddSkinMenu(ToolStripMenuItem toolMenu)
{
DataSet skin = new DataSet();
try
{
skin.ReadXml("skin.xml",XmlReadMode.Auto);
}
catch
{
}
if (skin==null||skin.Tables.Count < 1)
{
skin = new DataSet();
skin.Tables.Add("skin");
skin.Tables["skin"].Columns.Add("style");
System.Data.DataRow dr = skin.Tables["skin"].NewRow();
dr[0] = "系统默认";
skin.Tables[0].Rows.Add(dr);
skin.WriteXml("skin.xml", XmlWriteMode.IgnoreSchema);
}
foreach (SkinType st in (SkinType[])System.Enum.GetValues(typeof(SkinType)))
{
toolMenu.DropDownItems.Add(new ToolStripMenuItem(st.ToString()));
toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1].Click += new EventHandler(frm_Main_Click);
if (st.ToString() == skin.Tables[0].Rows[0][0].ToString())
{
((ToolStripMenuItem)toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1]).Checked = true;
frm_Main_Click(toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1], null);
}
}
toolMenu.DropDownItems.Add(new ToolStripMenuItem("系统默认"));
toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1].Click += new EventHandler(frm_Main_Click);
if (skin.Tables[0].Rows[0][0].ToString() == "系统默认")
{
((ToolStripMenuItem)toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1]).Checked = true;
}
}
#3
to: Sharp Shooter
findcontrol 是行不通的,因为查找的对象不是个 control 而是一个尚未实例化的 对象引用
to: alldj(灵山妖姬)
你的方法是可行的但,不是我想要的,我现在关问题是 能否通对 Winform 的名称来实例化该对
象
望朋友帮忙
findcontrol 是行不通的,因为查找的对象不是个 control 而是一个尚未实例化的 对象引用
to: alldj(灵山妖姬)
你的方法是可行的但,不是我想要的,我现在关问题是 能否通对 Winform 的名称来实例化该对
象
望朋友帮忙
#4
用反射做
先把submen.cs编译成.dll放在bin里
然后加载。
Assembly a = Assembly.Load("namespace.submen1.dll");
(Form)Activator.CreateInstance(a.GetTypes()).ShowDialog();
先把submen.cs编译成.dll放在bin里
然后加载。
Assembly a = Assembly.Load("namespace.submen1.dll");
(Form)Activator.CreateInstance(a.GetTypes()).ShowDialog();
#5
反射是可以,但是可能有些损耗性能
其实这种问题如果有个统一的命名规则的话、
直接findcontrol
或者将control和xml title 弄一个dictionary 调用
应该是个不错的解决方案
毕竟这样没有反射损耗性能
其实这种问题如果有个统一的命名规则的话、
直接findcontrol
或者将control和xml title 弄一个dictionary 调用
应该是个不错的解决方案
毕竟这样没有反射损耗性能
#6
如果你要调用的类直接就和主窗口在一个项目里的话,用
Assembly a = Assembly.GetExecutingAssembly()就可以获得当前的Assembly
然后Type t = a.GetType(类名)获得类(最好是带namespace的全名)
最后Activator.CreateInstance(t)即可,谨慎起见最好这三句套个try作意外处理
Assembly a = Assembly.GetExecutingAssembly()就可以获得当前的Assembly
然后Type t = a.GetType(类名)获得类(最好是带namespace的全名)
最后Activator.CreateInstance(t)即可,谨慎起见最好这三句套个try作意外处理
#7
测试中,谢谢大家的热心帮忙,测试完结贴,顶者有分
#8
private void button1_Click(object sender, EventArgs e)
{
string frm = "Form2";
for (int i = 0; i < Application.OpenForms.Count; i++)
{
if (Application.OpenForms[i].Name == frm)
{
return;
}
}
System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
//object obj=thisDll.CreateInstance("Form2");
Type typForm = ass.GetType( "testDLL."+frm );
if( typForm == null ) return;
Form frmTest = typForm.InvokeMember( null,BindingFlags.DeclaredOnly |BindingFlags.Public | BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.CreateInstance,null,null,null ) as Form;
if( frmTest == null ) return;
else
{
frmTest.Name=frm;
frmTest.Show();
}
}
{
string frm = "Form2";
for (int i = 0; i < Application.OpenForms.Count; i++)
{
if (Application.OpenForms[i].Name == frm)
{
return;
}
}
System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
//object obj=thisDll.CreateInstance("Form2");
Type typForm = ass.GetType( "testDLL."+frm );
if( typForm == null ) return;
Form frmTest = typForm.InvokeMember( null,BindingFlags.DeclaredOnly |BindingFlags.Public | BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.CreateInstance,null,null,null ) as Form;
if( frmTest == null ) return;
else
{
frmTest.Name=frm;
frmTest.Show();
}
}
#9
可用类工厂
#10
不行,我在Vs2003中不能用OpenForms的属性
#11
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindowEx")] //找子窗体
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll", EntryPoint = "SendMessage")] //用于发送信息给窗体
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
/// <summary>
/// 查找是否已创建窗体
/// </summary>
/// <param name="FormTitle">标题名称</param>
/// <returns></returns>
public static bool SearchForm(string FormTitle)
{
IntPtr ParenthWnd = new IntPtr(0);
IntPtr EdithWnd = new IntPtr(0);
//查到窗体,得到整个窗体
ParenthWnd = FindWindow(null,FormTitle);
if (!ParenthWnd.Equals(IntPtr.Zero))
{
return true;
}
else
{
return false;
}
}
private void button1_Click(object sender, EventArgs e)
{
string frm = "FormTitle";
if (SearchForm(frm))
{
return;
}
frm="Form2";
System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
//object obj=thisDll.CreateInstance("Form2");
Type typForm = ass.GetType( "testDLL."+frm );
if( typForm == null ) return;
Form frmTest = typForm.InvokeMember( null,BindingFlags.DeclaredOnly |BindingFlags.Public | BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.CreateInstance,null,null,null ) as Form;
if( frmTest == null ) return;
else
{
frmTest.Name=frm;
frmTest.Show();
}
}
#12
.net 反射机制
#13
to :alldj(灵山妖姬)
找不到BindingFlags
找不到BindingFlags
#14
学习
#15
System.Reflection.BindingFlags 可以,测试中
#16
可以了,谢谢大家
to :alldj(灵山妖姬)
你的方法可行
to :alldj(灵山妖姬)
你的方法可行