被树形菜单卡住了。。。

年轻的程序员小唐 2019-09-24 05:01:06
我又来提问了,首先C#0基础边工便自学两个月
我在做winform程序,之前都是做修改,添加控件,删除控件,调用控件的属性啥的
现在让我在原来的程序基础上做出一个新的软件,主要就是多了一个树形菜单跟tabcontrol的联动和动态增删是新的难点吧,这个问题困扰我太久了,因为原程序里是没有树形菜单的。我要完全自己创建写一个treeview的程序而且要动态增删的。
第一次做,想的这不就是一个控件吗,直接插入一个控件进去。。
后来往下做,这个控件的子节点还要能够增删,还要和tabcontrol的tabpage的增删联系起来,这个也还好,调用属性就做出来了,但是我做出来的这个并不算是动态加载的,只是能够增删而已
拿这个图举例,在节点“数字信道”下的子节点初始只有一个子节点“数字信道1”,然后可以增加,新加的子节点名字就是数字信道2、3、4、5、6这样按顺序下去,然后删除是打开了哪个节点就能够删除哪个节点。这一部分我做出来了的。

接下来问题来了,如图中所示,子节点被删除或者改名之后,增加节点,他的命名会从“数字信道1”开始,按顺序且不重复的增加子节点。

然后我做的。。。把中间的节点删除掉,再增加节点就只会往上加,因为我命名是用了一个变量一直++肯定会这样的,而且也没有命名是否重复的判断。然后我就开始想
但是吧,这个问题我琢磨了半天琢磨不出来咋做。。。因为我不会用数据库那些,只有简单的for,forreach,if这些简单的语句进行逻辑判断,结果这逻辑绕了半天把我给绕晕了,Name和Text的属性还有index我判断来判断去把我给整蒙了
贴一下给自己整晕了的代码

private void btn_add_Click(object sender, EventArgs e)
{
/* bool have = false;
if (tabControl1.SelectedTab.Name.Contains("信道") == true)
{
TreeNode tn = treeView1.SelectedNode.Parent;
if(tn.Nodes.Count==1)
{}
else
{
for (int i = 0; i < tn.Nodes.Count; i++)
{
if (tn.Nodes[i].Name == ("信道" + 1))
{
have = true;
break;
}
else
{ }
}
}
*/
//这一段注释起来的代码把我给绕晕了,我想着用for判断命名是否重复,后来反应过来这特么只能判断一个名字
if (tabControl1.SelectedTab.Name.Contains("信道")==true)
{
TreeNode tn = treeView1.SelectedNode.Parent;
FormChannel channel = new FormChannel(dataApplication, pagei);
Addchannel(channel);
tn.Nodes.Add("信道" + (pagei + 1));
pagei++;

}
//这一段就是很蠢的增加子节点的方法。。。
}

我去百度了很多做动态树形菜单的,有特别多的例子,思路也有:用递归遍历来判断命名是否重复来解决这个问题,但是呢,很多都用到了数据库还调用了什么sqlhelper类,可是我对数据库一窍不通啊。。。然后去找数据库教程看的也是一知半解。
我现在深感到自己技术的不足,想问问大家有没有不用数据库能够做出动态树形菜单的方法,或者偏简单向的(毕竟还是要快点交差嘛)并想要一个sql的菜鸡傻瓜教程
...全文
216 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 9 楼 damao_94 的回复:
有点捉摸不透你,如果后添加的只需要填充,比如有1,3,4,5时自动添加一个为2,就是从1开始循环查找这个应该是简单的做法了,如果要从最大的开始,就是自动添加6才是相对难的吧.可是看后面的回答,你似乎只要前者

我的需求相当于是填充吧,text的填充,为啥我觉得自动添加最大的相对简单呢,只需要比较出一个最大值然后加1不就好了吗
Dear200892 2019-09-25
  • 打赏
  • 举报
回复
假如你得到的子节点集合为list bool 是否添加=false; for(int i=0;i<list.count();i++) { //获取子节点的名字编号:如信道2=》2 int num=....... //如果不存在,追加元素 if(num!=i+1) { list.insert(i,node); 是否添加=ture; return; } } //如果没有添加断裂的节点,则在最后添加节点 if(!是否添加) { ..... }
  • 打赏
  • 举报
回复
引用 6 楼 Dear200892 的回复:
[quote=引用 5 楼 weixin_44246797 的回复:]
[quote=引用 2 楼 Dear200892 的回复:]
获取所有数字通信的子节点集合,排序选择最大的那个节点,根据节点编号+1创建新节点。

这样如果是中间的节点被删除了就不对了,比如1 3 5 9 那添加的节点编号不就是10吗[/quote]
你的意思是,新增的节点还需要填到原来被删除的位置呀?[/quote]
是要1 3 5 9 新增的应该是2 4 6 7 8,我刚刚弄出来了,代码贴在4楼
附上效果图
Dear200892 2019-09-25
  • 打赏
  • 举报
回复
引用 5 楼 weixin_44246797 的回复:
[quote=引用 2 楼 Dear200892 的回复:] 获取所有数字通信的子节点集合,排序选择最大的那个节点,根据节点编号+1创建新节点。
这样如果是中间的节点被删除了就不对了,比如1 3 5 9 那添加的节点编号不就是10吗[/quote] 你的意思是,新增的节点还需要填到原来被删除的位置呀?
  • 打赏
  • 举报
回复
引用 2 楼 Dear200892 的回复:
获取所有数字通信的子节点集合,排序选择最大的那个节点,根据节点编号+1创建新节点。

这样如果是中间的节点被删除了就不对了,比如1 3 5 9 那添加的节点编号不就是10吗
  • 打赏
  • 举报
回复

string NewNode = "";
int number = 1;
int pagei=1;//这个变量具体干啥用的一时半会儿想不起来了
private void btn_add_Click(object sender, EventArgs e)//添加节点和tabpage
{
bool include=false;
bool file = true;
TreeNode tn = treeView1.SelectedNode.Parent;
List <string> name=new List<string>();
List<string>channelname=new List<string>();
for (int i = 0; i < tn.Nodes.Count; i++)//先把子节点的text全添加到name集合里
{
name.Add(tn.Nodes[i].Text);
}
for (int j = 0; j < tn.Nodes.Count; j++)//将name集合里符合标准命名“信道j”的字符串筛选出来添加到channelname集合里
{
if (name.Contains("信道" + (j + 1)))
{ channelname.Add(tn.Nodes[j].Text); }
}
while(file)//
{
for(int k=0;k<tn.Nodes.Count;k++)//判断字符串““信道”+number”是否在被使用
{
if (tn.Nodes[k].Text == "信道" + number)
{
include = true;
break;//是则直接跳出for循环
}
else
{ include = false; }
}
if (include)
{
number++;
if (number > tn.Nodes.Count + 1)//这个if是为了防止无限循环,从逻辑上讲几乎不可能发生true的情况
{ file = false; }
}
else
{
NewNode = "信道" + number;//把新节点名赋值
file = false;
}
}
FormChannel channel = new FormChannel(dataApplication, pagei);
Addchannel(channel);
tn.Nodes.Add(NewNode);
pagei++;
public TabPage Addchannel(FormChannel form)//添加tabpage和窗体
{

form.TopLevel = false;
form.Dock = DockStyle.Fill;
form.FormBorderStyle = FormBorderStyle.None;
TabPage page = new TabPage();
page.Controls.Add(form);
form.Visible = true;
page.Text = NewNode;
page.Name = "信道" + (pagei + 1);
this.tabControl1.Controls.Add(page);
return page;
}
private void btn_delet_Click(object sender, EventArgs e)//删除节点tabpage
{
TreeNode stnp = treeView1.SelectedNode.Parent;
TreeNode stn = treeView1.SelectedNode;
if (stnp.Nodes.Count > 1)
{
for (int i = 0; i < stnp.Nodes.Count; i++)
{
if (stnp.Nodes[i].Text == tabControl1.SelectedTab.Name)
{ stn = stnp.Nodes[i]; }
else
{ }
}
tabControl1.TabPages.Remove(tabControl1.SelectedTab);//删除tabpage
stnp.Nodes.Remove(stn);//同时删除对应的节点
pagei--;
number = 1;//在这里把number复位为1才能使添加操作能够正常进行
}
else
{ }
}


这个是到目前为止我写的树形菜单和tabcontrol的动态添加删除,没有用到数据库0.0 这个应该能算动态吧
应该还会有很多的BUG和功能不够完善,我会在慢慢改进的,各位有啥意见或者建议欢迎提出!
谢谢大家的帮助!!!
  • 打赏
  • 举报
回复
引用 1 楼 stherix 的回复:
有2个办法
1.删掉某个信道后,后面的信道名 全部 -1,这样每次新增都会是最大的
2.for循环 i=1开始 查找 信道{i} 是否在当前节点的子节点名里 如果没有就增加并返回

法1不行,因为这个信道名要求是可以自定义的,所以名字不应该随着删改变化,会容易混淆
法2倒是启发我了现在写出来可以了,暂时不知道name的命名是啥情况,我把代码贴下面
Dear200892 2019-09-25
  • 打赏
  • 举报
回复
获取所有数字通信的子节点集合,排序选择最大的那个节点,根据节点编号+1创建新节点。
damao_94 2019-09-25
  • 打赏
  • 举报
回复
有点捉摸不透你,如果后添加的只需要填充,比如有1,3,4,5时自动添加一个为2,就是从1开始循环查找这个应该是简单的做法了,如果要从最大的开始,就是自动添加6才是相对难的吧.可是看后面的回答,你似乎只要前者
stherix 2019-09-24
  • 打赏
  • 举报
回复
有2个办法 1.删掉某个信道后,后面的信道名 全部 -1,这样每次新增都会是最大的 2.for循环 i=1开始 查找 信道{i} 是否在当前节点的子节点名里 如果没有就增加并返回

110,561

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧