类似于把窗体实例化的函数进行封装,其实就是一个C#自带的函数,当时用的时候在网上查了好久。
这个函数结合数据库来使用效果很好,就是不用重复的对窗体进行实例化,提高代码的简洁度。
我这里比较繁琐了些,因为想登陆界面不显示NarBarControl,我又多做了一层
这篇主要讲NarBarControl和XtraTabControl和Assembly实例化窗体的结合使用
NarBarControl结合数据库自动添加Group和Item的实例前面已有讲过,但是这里有一点小改动,这里把Item的URL换成了窗体的名称。这样做的目的就是接下来结合Assembly实例化窗体
数据库结构:
RibbonControl焦点页切换的时候给NarBarControl添加组
private void RBControl_SelectedPageChanged(object sender, EventArgs e)
{
if (RBControl.SelectedPage != null && RBControl.SelectedPage.Name.ToString().Trim() != "")
{
Frm_Split = Frm_Split.CreateFrom(this);
Frm_Split.TopLevel = false;
Frm_Split.Parent = Panel;
Frm_Split.Dock = DockStyle.Fill;
Frm_Split.Show();
page = RBControl.SelectedPage.Name.ToString().Trim();
Frm_Split.Menu.Groups.Clear();
DetailReportGroup(page, Frm_Split);
}
}
这里的Frm_Split实际上就是NarBarControl和XtraTabControl的窗体,加了一个SplitContainerControl的控件实现NarBarControl的左收缩。
循环动态添加NarBarControl的Group和Item
//循环添加组
private void DetailReportGroup(string pageName, Frm_Split frm)
{
string sql = "select isAdmin from UserInf where userID='" + lbl_userID.Caption.Trim().ToLower() + "' and isUse='Y'";
DataTable dt;
if (!DB.AF.execSql(sql, sqlconnks, out dt))
{
MessageBox.Show("连接服务器错误,请检查网络是否正常!");
return ;
}
if (dt.Rows.Count == 0)
{
MessageBox.Show("该用户账号不存在或已停用,请输入正确的用户!");
return ;
}
if (dt.Rows[0]["isAdmin"].ToString().Trim() == "Y")
{
sql = "select MenuID,MenuName from Sys_Menu where Flag = 'Group' and Isuse = 'Y' and Page = '" + pageName + "'";
}
else sql = "select a.MenuID MenuID,b.MenuName MenuName from sys_Menu_User a left join sys_Menu b on a.MenuID = b.MenuID where Flag = 'Group' and a.Isuse = 'Y' and b.Isuse = 'Y' and Page = '" + pageName + "' and userID = '" + lbl_userID.Caption.Trim() + "'";
dt.Clear();
if (!DB.AF.execSql(sql, sqlconn, out dt))
{
MessageBox.Show("查询菜单组失败!");
return;
}
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
NavBarGroup nbGroup = new NavBarGroup();
nbGroup.Name = dt.Rows[i]["MenuID"].ToString();
nbGroup.Caption = dt.Rows[i]["MenuName"].ToString();
frm.Menu.Groups.Add(nbGroup);
DetailReportItem(nbGroup, pageName);//这里调用Item的函数
}
}
}
//对组循环添加Item
private void DetailReportItem(NavBarGroup GroupName, string pageName)
{
string sql = "select isAdmin from UserInf where userID='" + lbl_userID.Caption.Trim().ToLower() + "' and isUse='Y'";
DataTable dt;
if (!DB.AF.execSql(sql, sqlconnks, out dt))
{
MessageBox.Show("连接服务器错误,请检查网络是否正常!");
return;
}
if (dt.Rows.Count == 0)
{
MessageBox.Show("该用户账号不存在或已停用,请输入正确的用户!");
return;
}
if (dt.Rows[0]["isAdmin"].ToString().Trim() == "Y")
{
sql = "select URL,MenuName from Sys_Menu where Flag = 'Item' and upID = '" + GroupName.Name + "' and Isuse = 'Y' and Page = '" + pageName + "'";
}
else sql = "select b.URL URL,b.MenuName MenuName from sys_Menu_User a left join sys_Menu b on a.MenuID = b.MenuID where Flag = 'Item' and upID = '" + GroupName.Name + "' and a.Isuse = 'Y' and b.Isuse = 'Y' and Page = '" + pageName + "' and userID = '"+lbl_userID.Caption.Trim()+"'";
dt.Clear();
if (!DB.AF.execSql(sql, sqlconn, out dt))
{
MessageBox.Show("查询菜单失败!");
return;
}
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
NavBarItem nbItem = new NavBarItem();
nbItem.Name = dt.Rows[i]["URL"].ToString();
nbItem.Caption = dt.Rows[i]["MenuName"].ToString();
nbItem.LinkClicked += Item_Click;
GroupName.ItemLinks.Add(nbItem);
}
}
}
我这里还涉及到了账户菜单权限的一小部分内容,只需要看Admin的那部分就行。
接下来是Item的点击事件和Assembly窗体实例化的部分:
#region 窗体实例化
private void Item_Click(object sender, NavBarLinkEventArgs e)
{
FormName = MidStrEx(e.Link.Item.Name,"_","_");
if (FormName.Length > 0)
{
bool bzj = false;
if (Frm_Split.tabs.Controls.Count != 0)
{
foreach (XtraTabPage page in Frm_Split.tabs.TabPages)
{
if (page.Name == e.Link.Item.Name)
{
bzj = true;
Frm_Split.tabs.SelectedTabPage = page;
return;
}
}
}
if (bzj == false)
{
XtraTabPage tabFrmLog = new XtraTabPage();
tabFrmLog.Text = e.Link.Caption;
tabFrmLog.Name = e.Link.Item.Name;
//初始化登录界面
CreateForm(namespaceName + "." + FormName + "." + e.Link.Item.Name, namespaceName, tabFrmLog, Frm_Split, lbl_userID.Caption.Trim(), btn_UserName.Caption.Trim());
//子窗体大小设置为选项卡大小
Frm_Split.tabs.TabPages.Add(tabFrmLog);
Frm_Split.tabs.SelectedTabPage = tabFrmLog;
}
}
}
/// <summary>
/// 打开新的子窗体
/// </summary>
/// <param name="strName">窗体的类名</param>
/// <param name="AssemblyName">窗体所在类库的名称</param>
public static void CreateForm(string strName, string AssemblyName , XtraTabPage tabFrmLog,Frm_Split Frm_Split,string userID,string UserName)
{
string path = AssemblyName;//项目的Assembly选项名称
string name = strName; //类的名字
//XtraMessageBox.Show(path + ";" + name);
object[] args = new object[3];
args[0] = Frm_Split;
args[1] = userID;
args[2] = UserName;
Form doc = (Form)Assembly.Load(path).CreateInstance(name, true, System.Reflection.BindingFlags.Default, null, args, null, null);
doc.TopLevel = false;
doc.Dock = DockStyle.Fill;
doc.FormBorderStyle = FormBorderStyle.None;
tabFrmLog.Controls.Add(doc);
doc.Show();
}
public static string MidStrEx(string sourse, string startstr, string endstr)
{
string result = string.Empty;
int startindex, endindex;
try
{
startindex = sourse.IndexOf(startstr);
if (startindex == -1)
return result;
string tmpstr = sourse.Substring(startindex + startstr.Length);
endindex = tmpstr.IndexOf(endstr);
if (endindex == -1)
return result;
result = tmpstr.Remove(endindex);
}
catch (Exception ex)
{
XtraMessageBox.Show("MidStrEx Err:" + ex.Message);
}
return result;
}
我这里需要用到MidStrEx()函数的原因是因为我把窗体放在了文件夹下面,如果直接放在项目下则不需要这个函数