用MVC做WinForm客户端

昨天突然脑洞大开,觉得WinForm客户端也可以做成MVC!想到就做!于是把以前做的一个WinForm工程拉出来,选了角色权限模块先试个水。

第一步:调整项目结构,调整后结构如下图:

第二步:拆分逻辑

原来整个窗体类里面包含了很多业务逻辑,这部分不用说,直接拆分到Controller里面,还有工具栏点击事件的处理逻辑,也同样分离出来放到Controller里面。拆分之后,窗体类就变成了一个纯粹的View了。至于Model,就是拖进一个叫Model的文件夹里面就好了。

第三步:处理命名空间变化带来的一系列问题。大概花了两小时,部分重构完成,程序运行正常!


总结:重构后逻辑更加清晰,任务更容易分解,也更容易进行单元测试。这个思路个人认为值得推广。

部分代码:

Manager:

using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.XtraBars;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraTreeList;
using Insight.WS.Client.Base.Role.Controller;
using Insight.WS.Client.Base.Role.Model;
using Insight.WS.Client.Common;

namespace Insight.WS.Client.Base.Role.View
{
    public partial class Manager : MdiBase
    {

        #region 变量声明

        public static List<RoleInfo> Roles;
        public static RoleInfo Role;
        private bool First = true;

        #endregion

        #region 构造函数

        public Manager()
        {
            InitializeComponent();

            // 注册事件
            gdvRole.FocusedRowObjectChanged += gdvRole_FocusedRowObjectChanged;
            treMember.CustomDrawNodeImages += CustomDrawNodeImages;
            treModule.CustomDrawNodeImages += DrawNodeImages;
            treAction.CustomDrawNodeImages += DrawNodeImages;
            treData.CustomDrawNodeImages += DrawNodeImages;
        }

        #endregion

        #region 界面事件处理

        /// <summary>
        /// 窗体加载时初始化控件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RoleManage_Load(object sender, EventArgs e)
        {
            InitToolBar();
            Roles = new List<RoleInfo>();
            Role = new RoleInfo();

            // 初始化角色列表
            grdRole.DataSource = Roles;
            Format.GridFormat(gdvRole);

            // 初始化角色成员
            treMember.SelectImageList = imgMember;
            treMember.DataSource = Role.Members;
            Format.TreeFormat(treMember);

            // 初始化角色成员用户
            grdUser.DataSource = Role.Users;
            Format.GridFormat(gdvUser);

            // 初始化业务模块列表
            treModule.SelectImageList = imgPermission;
            treModule.DataSource = Role.Modules;
            Format.TreeFormat(treModule);

            // 初始化操作权限列表
            treAction.DataSource = Role.Actions;
            Format.TreeFormat(treAction);
            treAction.SelectImageList = imgPermission;

            // 初始化数据权限列表
            treData.DataSource = Role.Datas;
            Format.TreeFormat(treData);
            treData.SelectImageList = imgData;
        }

        /// <summary>
        /// 窗体显示时加载数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Manager_Shown(object sender, EventArgs e)
        {
            General.InitRoleList();

            grdRole.DataSource = Roles;
            gdvRole.MoveFirst();
        }

        /// <summary>
        /// 角色列表选中行变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gdvRole_FocusedRowObjectChanged(object sender, FocusedRowObjectChangedEventArgs e)
        {
            Role = (RoleInfo) gdvRole.GetFocusedRow();
            var dict = new Dictionary<string, bool>
            {
                {"DeleteRole", !Role.BuiltIn},
                {"AddMember", !Role.BuiltIn}
            };
            SwitchItemStatus(dict);

            treMember.DataSource = Role.Members;
            treMember.ExpandAll();

            grdUser.DataSource = Role.Users;

            treData.DataSource = Role.Datas;
            treData.ExpandToLevel(0);
            treData.MoveFirst();

            treAction.DataSource = Role.Actions;
            treAction.ExpandToLevel(0);
            treAction.MoveFirst();

            treModule.DataSource = Role.Modules;
            treModule.ExpandAll();
            treModule.MoveFirst();

            if (!First) return;

            tabPermission.SelectedTabPageIndex = 1;
            tabPermission.SelectedTabPageIndex = 0;
            First = false;
        }

        /// <summary>
        /// 切换角色成员
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treMember_FocusedNodeChanged(object sender, FocusedNodeChangedEventArgs e)
        {
            if (treMember.FocusedNode == null) return;

            var canRemove = !Role.BuiltIn && (int)treMember.FocusedNode.GetValue("NodeType") != 0;
            var dict = new Dictionary<string, bool>
            {
                {"Remove", canRemove}
            };
            SwitchItemStatus(dict);
        }

        /// <summary>
        /// 双击角色列表编辑当前所选角色
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gdvRole_DoubleClick(object sender, EventArgs e)
        {
            var id = (Guid) gdvRole.GetFocusedDataRow()["ID"];
            var edit = barManager.Items["EditRole"];
            if (gdvRole.FocusedRowHandle < 0 || !edit.Enabled) return;

            Event.RoleEdit(true, id);
        }

        /// <summary>
        /// 显示角色成员的类型图标
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CustomDrawNodeImages(object sender, CustomDrawNodeImagesEventArgs e)
        {
            if (e.Node.Level != 0) return;

            e.SelectImageIndex = Convert.ToInt32(e.Node.GetValue("MemberId").ToString().Substring(0, 1));
        }

        /// <summary>
        /// 重绘模块功能树节点图标
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DrawNodeImages(object sender, CustomDrawNodeImagesEventArgs e)
        {
            e.SelectImageIndex = (int)e.Node.GetValue("Type");
        }

        /// <summary>
        /// 重载菜单列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected override void item_ItemClick(object sender, ItemClickEventArgs e)
        {
            switch (e.Item.Name)
            {
                case "Refresh":
                    General.InitRoleList();
                    break;

                case "NewRole":
                    Event.RoleEdit(false, Guid.Empty);
                    gdvRole.FocusedRowHandle = gdvRole.GetRowHandle(Roles.Count - 1);
                    break;

                case "EditRole":
                    var id = (Guid)gdvRole.GetFocusedDataRow()["ID"];
                    Event.RoleEdit(true, id);
                    break;

                case "DeleteRole":
                    Event.RoleDelete();
                    gdvRole.RefreshData();
                    break;

                case "AddMember":
                    Event.MemberAdd();
                    break;

                case "Remove":
                    var mid = (Guid) treMember.FocusedNode.GetValue("ID");
                    var member = Role.Members.Single(m => m.ID == mid);
                    Event.MemberRemove(member);
                    treMember.RefreshDataSource();
                    break;
            }
        }

        #endregion

    }
}


Event:

using System;
using System.Windows.Forms;
using Insight.WS.Client.Base.Role.Model;
using Insight.WS.Client.Base.Role.View;
using static Insight.WS.Client.Common.Util.Message;

namespace Insight.WS.Client.Base.Role.Controller
{
    public class Event
    {
        #region Manager

        /// <summary>
        /// 新建/编辑当前所选角色
        /// </summary>
        /// <param name="isEdit"></param>
        /// <param name="id"></param>
        public static void RoleEdit(bool isEdit, Guid id)
        {
            var dig = new Wizard
            {
                IsEdit = isEdit,
                ObjectId = id
            };
            dig.Close();
        }

        /// <summary>
        /// 删除当前所选角色
        /// </summary>
        public static void RoleDelete()
        {
            var msg = $"您确定要删除角色【{Manager.Role.Name}】吗?\r\n角色删除后将无法恢复!";
            if (ShowConfirm(msg) != DialogResult.OK) return;

            var result = Repository.RemoveRole(Manager.Role.ID);
            if (!result.Successful)
            {
                ShowError($"{result.Message}\r\n对不起,角色【{Manager.Role.Name}】删除失败!如多次删除失败,请联系管理员。");
                return;
            }

            Manager.Roles.Remove(Manager.Role);
        }

        /// <summary>
        /// 为当前所选角色添加成员
        /// </summary>
        public static void MemberAdd()
        {
            var dig = new Member();
            dig.Close();
        }

        /// <summary>
        /// 删除当前所选角色成员
        /// </summary>
        public static void MemberRemove(RoleMember member)
        {
            var msg = $"您确定要移除角色成员【{member.Member}】吗?\r\n角色成员被移除后相应用户将失去该角色赋予的权限!";
            if (ShowConfirm(msg) != DialogResult.OK) return;

            var result = Repository.RemoveRoleMember(member.MemberId, member.NodeType);
            if (!result.Successful)
            {
                ShowError($"{result.Message}\r\n对不起,角色成员【{member.Member}】移除失败!如多次移除失败,请联系管理员。");
                return;
            }

            Manager.Role.Members.Remove(member);
        }

        #endregion
    }
}

Repository:

using System;
using Insight.WS.Client.Common.Entity;
using static Insight.WS.Client.Common.Util.HttpHelper;
using static Insight.WS.Client.Common.Util.Utils;

namespace Insight.WS.Client.Base.Role.Controller
{
    public class Repository
    {
        /// <summary>
        /// 删除指定角色
        /// </summary>
        /// <returns>JsonResult</returns>
        public static JsonResult RemoveRole(Guid id)
        {
            var url = BaseServer + $"r/roles/{id}";
            return HttpRequest(url, "DELETE", AutherKey);
        }

        /// <summary>
        /// 获取所有角色
        /// </summary>
        /// <returns>JsonResult</returns>
        public static JsonResult GetRoles()
        {
            var url = BaseServer + "r/roles";
            return HttpRequest(url, "GET", AutherKey);
        }

        /// <summary>
        /// 删除指定角色成员
        /// </summary>
        /// <param name="id">成员关系ID</param>
        /// <param name="type">成员类型</param>
        /// <returns>JsonResult</returns>
        public static JsonResult RemoveRoleMember(Guid id, int type)
        {
            var url = BaseServer + $"r/roles/members/{id}?type={type}";
            return HttpRequest(url, "DELETE", AutherKey);
        }

    }
}




  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值