DevExpress AccordionControl 左侧导航
1 SQL创建菜单表
CREATE TABLE [dbo].[pubMenuInfo1]
(
[uMenuID] [uniqueidentifier] NOT NULL,
[sMenuID] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL,
[sMenuName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL,
[sDescript] [varchar] (100) COLLATE Chinese_PRC_CI_AS NULL,
[uSysID] [uniqueidentifier] NOT NULL,
[sParentMenuName] [varchar] (100) COLLATE Chinese_PRC_CI_AS NOT NULL,
[uParentMenuID] [uniqueidentifier] NULL,
[bUsable] [bit] NOT NULL,
[sClassPath] [nvarchar] (200) COLLATE Chinese_PRC_CI_AS NULL,-- 调用窗体的类 用逗号分开 程序集,命名空间,类名
[sParameter] [varchar] (100) COLLATE Chinese_PRC_CI_AS NULL -- 调用窗体的类的参数 用逗号分开 参数1,参数2
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[pubMenuInfo1] ADD CONSTRAINT [PK_pubMenuInfo1] PRIMARY KEY CLUSTERED ([uMenuID]) ON [PRIMARY]
GO
2 根据菜单表生成菜单
2.1 生成父菜单
// 查询菜单数据
dsMenu1 = database.GetDataSource(@" SELECT uMenuID ,
sMenuID ,
sMenuName ,
sDescript ,
uSysID ,
sParentMenuName ,
uParentMenuID ,
uParentMenuID as uPID,
bUsable
,sClassPath ,
sParameter
FROM dbo.pubMenuInfo1 WITH(NOLOCK) "
+ " Where bUsable=1 order by sMenuID",
DataBaseOperate.strConnection, "menu");
// AccordionControl 生成父菜单
acControl.Elements.Clear();
acControl.BeginUpdate();
List<AccordionControlElement> lsRoot = new List<AccordionControlElement>();
// 找到根节点 g.Field<string>("sParentMenuName") == ""
var group = from g in dsMenu1.Tables[0].AsEnumerable()
where (g.Field<string>("sParentMenuName") == "" )
select new
{
sMenuID = g.Field<string>("sMenuID"),
sMenuName = g.Field<string>("sMenuName"),
sParentMenuName = g.Field<string>("sParentMenuName")
};
foreach (var gp in group) //
{
var acRootGroupHome = new AccordionControlElement();
acRootGroupHome.Name = gp.sMenuID;
acRootGroupHome.Text = gp.sMenuName;
var SUBCOUNT = dsMenu1.Tables[0].AsEnumerable()
.Where(LL => LL.Field<string>("sParentMenuName") == gp.sMenuName).Count();
if (SUBCOUNT > 0)//没有下级节点
{
//acRootGroupHome 节点有子节点则【递归】
additem(gp.sMenuName, acRootGroupHome);
}
根节点 添加到 acControl
acControl.Elements.Add(acRootGroupHome);
}
acControl.ElementClick += new ElementClickEventHandler(this.accordionControl1_ElementClick);
acControl.EndUpdate();
2.2 添加子菜单
//-------------------添加子菜单
private void additem(string sMenuName, AccordionControlElement ACEGROUP)
{
try
{
// 查找子菜单
var qitem = from k in dsMenu1.Tables[0].AsEnumerable()
where (k.Field<string>("sParentMenuName") == sMenuName)
select new
{
sMenuID = k.Field<string>("sMenuID"),
sMenuName = k.Field<string>("sMenuName"),
sParentMenuName = k.Field<string>("sParentMenuName")
};
foreach (var k in qitem)
{
var SubItem = new AccordionControlElement();
SubItem.Name = k.sMenuID;
SubItem.Text = k.sMenuName;
var SUBCOUNT = dsMenu1.Tables[0].AsEnumerable()
.Where(LL => LL.Field<string>("sParentMenuName") == SubItem.Text).Count();
if (SUBCOUNT == 0)//没有下级节点
{
SubItem.Style = ElementStyle.Item;
SubItem.Tag = SubItem.Name;
}
else
{
//有下级节点 递归
additem(SubItem.Text, SubItem);
}
子节点 加入父节点
ACEGROUP.Elements.AddRange(new AccordionControlElement[]
{ SubItem });
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
2.3 菜单点击事件
通过反射调用类的方法
//-------------------执行菜单点击事件
private void accordionControl1_ElementClick(object sender, DevExpress.XtraBars.Navigation.ElementClickEventArgs e)
{
if (e.Element.Style == ElementStyle.Group)
return;
if (e.Element.Tag == null) return;
var sMenuID = e.Element.Name;
// 得到 调用打开窗体的类, 参数
string itemID = e.Element.Tag.ToString();
var dr = dsMenu1.Tables[0].Select($"sMenuID='{sMenuID}'");
FormOpenParameters c1 = new FormOpenParameters();
object[] oParameter = null;
if (dr[0]["sParameter"].ToString() != "")
{
c1.p_arry = dr[0]["sParameter"].ToString().Split(',');
oParameter = new object[] { c1 };
}
else
{
oParameter = new object[] { "" };
}
var sClassPath = dr[0]["sClassPath"].ToString().Split(',');// 调用窗体类的路径
string assemblyName = sClassPath[0];
string nameSpace = sClassPath[1];
string className = sClassPath[2];
string methodName = sClassPath[3];
GetInvokeMethod(assemblyName, nameSpace, className, methodName, oParameter);
}
//------------------------------------------------------------------------------------------------------------------------------------------
// 窗体参数类
public class FormOpenParameters
{
public string[] p_arry;// 参数数组 打开窗体传入参数
}
#region 反射调用类的方法实例
/// <summary>
/// 调用方法实例
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="assemblyName">程序集名称</param>
/// <param name="nameSpace">命名空间</param>
/// <param name="className">类名</param>
/// <returns></returns>
public void GetInvokeMethod(string assemblyName, string nameSpace, string className, string methodName, object[] paras)
{
try
{
//获取程序集集合,找出需要用的那个
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
Assembly assembly = assemblies.Where(p => p.FullName.Contains(assemblyName)).FirstOrDefault();
//命名空间.类名
string path = nameSpace + "." + className;//+ "," + assemblyName
//加载类型
//Type type = Type.GetType(path);
Type type = assembly.GetType(path);
if (type == null)
{
throw new Exception("窗体未找到");
}
//根据类型创建实例
object obj = Activator.CreateInstance(type, true);
if (obj == null)
{
throw new Exception("窗体创建失败");
}
//加载方法参数类型及方法
MethodInfo method = null;
if (paras != null && paras.Length > 0)
{
//加载方法参数类型
Type[] paratypes = new Type[paras.Length];
for (int i = 0; i < paras.Length; i++)
{
paratypes[i] = paras[i].GetType();
}
//加载有参方法 调用public方法
method = type.GetMethod(methodName, paratypes);
}
else
{
//加载无参方法
method = type.GetMethod(methodName);
}
if (method == null)
{
throw new Exception("方法未找到");
}
//调用方法
method.Invoke(obj, paras);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion