winform的子窗体关闭刷新主窗体绑定数据以及刷新的总结

1.其实实现主窗体的刷新无非就是比较简单的调用load事件重新加载数据绑定,但是这样的效果会带来,无状态刷新,页面无法保存上一次的页面状态,比如

刷新前

刷新后

,如果点击刷新按钮执行的话,那么树形菜单会恢复关闭状态,那么如何实现这种刷新保持状态的效果呢?我们这边可以通过两个方法进行实现,原理未为:使用Hashtable来保存每个节点的状态.在把所有Nodes清空掉之前遍历TreeView,取得每个节点的状态,然后根据DataSet重新添加Nodes,添加完成后得根据刚才建立的Hashtable信息来设置每个节点的状态

代码如下:

主要就是给TreeView添加Nodes的前面和后面分别添加上这两个函数GetTreeNodesStatus(tv.Nodes);SetTreeNodesStatus(tv.Nodes);

 //绑定根节点      
        private void BindRoot()
        {
            GetTreeNodesStatus(treeView1.Nodes);//在这里绑定前的节点状态获取保存
            DataRow[] rows = dt.Select("FID=0");//取根   
            this.treeView1.Nodes.Clear();//多次加载前的清理
            foreach (DataRow dRow in rows)
            {
                TreeNode rootNode = new TreeNode();
                rootNode.Tag = dRow;
                rootNode.ImageIndex = 1;
                rootNode.SelectedImageIndex = 1;
                rootNode.Text = dRow["REPORTNAME"].ToString();
                this.treeView1.Nodes.Add(rootNode);
                BindChildAreas(rootNode);
            }
        }
        //递归绑定子节点
        private void BindChildAreas(TreeNode fNode)
        {
            DataRow dr = (DataRow)fNode.Tag;
            //父节点数据关联的数据行           
            int fid = Convert.ToInt32(dr["ID"].ToString());
            //父节点ID           
            DataRow[] rows = dt.Select("fid=" + fid);//子区域        
            if (rows.Length == 0) //递归终止,区域不包含子区域时          
            { return; }
            foreach (DataRow dRow in rows)
            {
                TreeNode node = new TreeNode();
                node.Tag = dRow; node.Text = dRow["REPORTNAME"].ToString(); //添加子点 
                //如果dRow["IFEND"]=0说明是类型,应该用文件夹
                if (Convert.ToInt32(dRow["IFEND"])== 0)
                {
                    node.ImageIndex = 1;
                    node.SelectedImageIndex = 1;
                }
                else 
                {
                    //对报表进行图标区分
                    if (dRow["REPORTTYPE"].ToString() == "production")
                    {
                        node.ImageIndex = 2; node.SelectedImageIndex = 2;
                    }
                    else { node.ImageIndex = 0; node.SelectedImageIndex = 0; }
                }               
                fNode.Nodes.Add(node);               //递归              
                BindChildAreas(node);
            }
            SetTreeNodesStatus(treeView1.Nodes);//绑定后的节点状态设置
        }

 /// <summary>
        /// 保存TreeNode状态
        /// </summary>
        /// <param name="nodes"></param>
        private void GetTreeNodesStatus(TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                if (node.IsExpanded)
                {
                    NodesStatus[node.FullPath] = true;
                }
                else
                {
                    NodesStatus.Remove(node.FullPath);
                }
                if (node.IsSelected)
                {
                    SelectNodeFullPath = node.FullPath;
                }
                GetTreeNodesStatus(node.Nodes);
            }
        }

        /// <summary>
        /// 设置TreeNode状态
        /// </summary>
        /// <param name="nodes"></param>
        private void SetTreeNodesStatus(TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                if (NodesStatus[node.FullPath] != null)
                {
                    node.Expand();
                }
                if (node.FullPath == SelectNodeFullPath)
                {
                    this.treeView1.SelectedNode = node;
                }
                SetTreeNodesStatus(node.Nodes);
            }
        }

 通过以上代码在load事件中重新加载的话,就不会再关闭节点了,会保持当前状态;

第二个问题来了,如何在子窗体中增加数据后绑定到主窗体显示,在子窗体关闭的时候展示在列表中?

我们这边可以通过两种方式进行实现:

第一种:1.在父窗体弹出子窗体的事件打开ShowDialog()之前,对父窗体做一个hide的假关闭

ChildForm fr2 = new ChildForm ();
this.Hide();
fr2.ShowDialog();

然后在子窗体的处理事件中,数据处理后的回调,对父窗体隐藏做一个展示效果

this.Close();

ParentForm fr2 = new ParentForm ();

fr2.ShowDialog();

以上就是第一种方式处理,但是这样处理增加或者修改数据的话,返回到主窗体后,主窗体还是一个关闭树的状态效果,无法保持上一次展开树菜单的效果?

因此我们需要考虑,在子窗体关闭之后,需要调用我们一开始说的绑定树列表的方法,里面会记录状态,那么我们如何去调用主窗体的这个绑定过程呢?

第二种:1.定义一个绑定的方法,无参数的绑定方法

//子窗体调用重新加载数据的方法
        public void reLoad_method()
        {
            //窗体数据初始化方法,父窗体中的全部操作,调用此方法可实现数据的刷新
            InitDataTable();
            BindRoot();
            BindViewList(rtsno);//rtsno为全局sno
        }

2.父窗体弹出子窗体的事件打开ShowDialog()之前,设置拥有此窗体的窗体 

ChildForm fr2 = new ChildForm (l);
fr2.Owner = this;
fr2.ShowDialog();

3.在子窗体中调用父窗体的加载记录状态的方法

ParentForm fr;
                fr= (ParentForm)this.Owner;
                fr.reLoad_method();//reLoad_method就是重新加载数据的函数

总结:第二种方式体验效果更直观,也能对主窗体的状态记录有一个保持,就不会回填之后主窗体被重新加载状态消失。

 

在这次开发过程中,出现了一个问题,就是窗体弹出来的事件show和showDialog的区别,用的第二种方法,如果直接弹出子窗体用show事件的话,那么子窗体调用父窗体加载记录方法会抛异常,如果用showDialog的话,就不会出现异常的问题,这两者的区别具体见博客:https://blog.csdn.net/xingkongtianyuzhao/article/details/104067642

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值