C# DevExpress WinForm编程 针对一些控件重复度高的属性设置问题的解决方案

原创 2017年12月26日 10:33:21

问题描述

我在使用DevExpress控件时经常会需要先将控件设置成自己需要的样式或者取消控件的一部分功能(可删除、可拖曳之类的)。这种行为本身并没什么问题,问题在于DevExpress控件的属性实在是太多了,多到我每次打开属性界面都会头痛。

解决方案

为了解决这个问题我使用了工具类提取控件属性的方法。
如下图,我将XtraForm传入了ZXtraFormTools这个工具类,也将菜单Bar对象传入了ZXtraBarTools工具类进行常用属性的设置。
这里写图片描述

这两个工具类的属性视图只保留了我要用的属性。
这里写图片描述 这里写图片描述

能看到这里的大家应该都懂了,下面直接放代码。

ZXtraFormTools.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using DevExpress.XtraEditors;


namespace ZDevExpressTools {
    public class ZXtraFormTools : ZComponentTools<XtraForm> {

        [Browsable(true), DefaultValue(null), DXCategory("对象引用")]
        public XtraForm XtraForm {
            get {
                return this.OperationObject;
            }
            set {
                this.OperationObject = value;
            }
        }

        [Browsable(true), DXCategory("视图选项")]
        public bool ShowIcon {
            get {
                if (this.XtraForm != null) {
                    return this.XtraForm.ShowIcon;
                }
                return false;
            }
            set {
                if (this.XtraForm != null) {
                    this.XtraForm.ShowIcon = value;
                }
            }
        }

        [AmbientValue("")]
        [Localizable(true)]
        [Browsable(true), DXCategory("视图选项")]
        public Icon Icon {
            get {
                if (this.XtraForm != null) {
                    return this.XtraForm.Icon;
                }
                return null;
            }
            set {
                if (this.XtraForm != null) {
                    this.XtraForm.Icon = value;
                }
            }
        }

        [Browsable(true), DXCategory("视图选项")]
        public string Text {
            get {
                if (this.XtraForm != null) {
                    return this.XtraForm.Text;
                }
                return null;
            }
            set {
                if (this.XtraForm != null) {
                    this.XtraForm.Text = value;
                }
            }
        }

        [Category("常用属性")]
        public bool ShowInTaskbar {
            get {
                if (this.XtraForm != null) {
                    return this.XtraForm.ShowInTaskbar;
                }
                return false;
            }
            set {
                if (this.XtraForm != null) {
                    this.XtraForm.ShowInTaskbar = value;
                }
            }
        }

        [Category("常用属性")]
        public bool MaximizeBox {
            get {
                if (this.XtraForm != null) {
                    return this.XtraForm.MaximizeBox;
                }
                return false;
            }
            set {
                if (this.XtraForm != null) {
                    this.XtraForm.MaximizeBox = value;
                }
            }
        }

        [Category("常用属性")]
        public bool MinimizeBox {
            get {
                if (this.XtraForm != null) {
                    return this.XtraForm.MinimizeBox;
                }
                return false;
            }
            set {
                if (this.XtraForm != null) {
                    this.XtraForm.MinimizeBox = value;
                }
            }
        }

        [Localizable(true)]
        [Category("常用属性")]
        public FormStartPosition StartPosition {
            get {
                if (this.XtraForm != null) {
                    return this.XtraForm.StartPosition;
                }
                return FormStartPosition.WindowsDefaultLocation;
            }
            set {
                if (this.XtraForm != null) {
                    this.XtraForm.StartPosition = value;

                }
            }
        }

        [DispId(-504)]
        [Category("常用属性")]
        public FormBorderStyle FormBorderStyle {
            get {
                if (this.XtraForm != null) {
                    return this.XtraForm.FormBorderStyle;
                }
                return System.Windows.Forms.FormBorderStyle.None;
            }
            set {
                if (this.XtraForm != null) {
                    this.XtraForm.FormBorderStyle = value;
                }
            }
        }

        [Category("常用属性")]
        public bool TopMast {
            get {
                if (this.XtraForm != null) {
                    return this.XtraForm.TopMost;
                }
                return false;
            }
            set {
                if (this.XtraForm != null) {
                    this.XtraForm.TopMost = value;
                }
            }
        }
    }
}

ZXtraBarTools.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Drawing;
using DevExpress.XtraEditors;
using DevExpress.XtraBars;
using DevExpress.Utils;
using DevExpress.Utils.Design;
using DevExpress.Utils.Serializing;

namespace ZDevExpressTools {
    public class ZXtraBarTools : Component {
        private Bar bar;
        [Browsable(true), Category("对象引用")]
        public Bar Bar {
            get {
                return bar;
            }
            set {
                bar = value;
            }
        }

        #region 常用属性

        [Browsable(true), Category("常用属性")]
        public bool AllowDelete {
            get {
                if (Bar != null) {
                    return Bar.OptionsBar.AllowDelete;
                } else {
                    return false;
                }
            }
            set {
                if (Bar != null) {
                    Bar.OptionsBar.AllowDelete = value;
                }
            }
        }

        [Browsable(true), Category("常用属性")]
        public bool AllowQuickCustomization {
            get {
                if (Bar != null) {
                    return Bar.OptionsBar.AllowQuickCustomization;
                } else {
                    return false;
                }
            }
            set {
                if (Bar != null) {
                    Bar.OptionsBar.AllowQuickCustomization = value;
                }
            }
        }

        [Browsable(true), Category("常用属性")]
        public bool DrawDragBorder {
            get {
                if (Bar != null) {
                    return Bar.OptionsBar.DrawDragBorder;
                } else {
                    return false;
                }
            }
            set {
                if (Bar != null) {
                    Bar.OptionsBar.DrawDragBorder = value;
                }
            }
        }

        [Browsable(true), Category("常用属性")]
        public bool MultiLine {
            get {
                if (Bar != null) {
                    return Bar.OptionsBar.MultiLine;
                } else {
                    return false;
                }
            }
            set {
                if (Bar != null) {
                    Bar.OptionsBar.MultiLine = value;
                }
            }
        }

        [Browsable(true), Category("常用属性")]
        public bool UseWholeRow {
            get {
                if (Bar != null) {
                    return Bar.OptionsBar.UseWholeRow;
                } else {
                    return false;
                }
            }
            set {
                if (Bar != null) {
                    Bar.OptionsBar.UseWholeRow = value;
                }
            }
        }
        #endregion

        [DXCategory("Font")]
        [DXDisplayName(typeof(ResFinder), "PropertyNamesRes", "DevExpress.Utils.AppearanceObject.Font")]
        [Localizable(true)]
        [RefreshProperties(RefreshProperties.All)]
        [TypeConverter(typeof(FontTypeConverter))]
        [XtraSerializableProperty]
        public Font Font {
            get {
                if (Bar != null) {
                    return Bar.BarAppearance.Normal.Font;
                } else {
                    return null;
                }
            }
            set {
                if (Bar != null) {
                    Bar.BarAppearance.Normal.Font = value;
                    Bar.BarAppearance.Pressed.Font = value;
                    Bar.BarAppearance.Hovered.Font = value;
                    Bar.BarAppearance.Disabled.Font = value;
                } else {

                }
            }
        }
    }
}

可能会碰到的问题

这个方案其实有一个问题,就是Winform的对象初始化顺序(上例不会碰到这个问题,因为控件拖放在工具类之前)。就算在设计视图中看到的是正常的,实际运行的时候可能是另一个样子。针对这个问题我的解决方案是当工具类实例加载对象时重载设置。

代码有点复杂,包含了对控件属性的加载、重置以及复用。实际就是用Attribute标识需要重载的属性,再用反射机制赋值。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Reflection;
using ZTools;

namespace ZDevExpressTools {

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class ZComponentTools<T> : Component where T : Component {

        private bool allowReuse = false;
        /// <summary>
        /// 允许复用
        /// </summary>
        [Browsable(true), DefaultValue(false), Category("复用设置")]
        public bool AllowReuse {
            get {
                return allowReuse;
            }
            set {
                allowReuse = value;
            }
        }

        private T operationObject;
        [Category("对象引用")]
        /// <summary>
        /// 操作对象
        /// </summary>
        public T OperationObject {
            get {
                return this.operationObject;
            }
            set {
                if (this.operationObject == null) {
                    //LoadSettings
                    //若原来的操作对象为空则加载属性
                    this.LoadSettings(value);
                } else {
                    if (this.AllowReuse == true) {
                        //ReuseSettings
                        //若原来的操作对象不为空 且 Tools需要复用 则 复用属性
                        this.ReuseSettings(value);
                    } else {
                        //ResetSettings
                        //若原来的操作对象不为空 且 Tools不需要复用 则 重设属性
                        this.ResetSettings();
                    }
                }
                this.operationObject = value;
            }
        }

        /// <summary>
        /// 复用Tools的设置
        /// </summary>
        /// <param name="obj"></param>
        public void ReuseSettings(T obj) {
            //1.取出对象中包含指令特性的成员属性
            List<PropertyInfo> list = ZAttrGetter.GetPropertyInfosConformAttribute(this, typeof(ZComponentToolsSettingsAttribute));
            List<PropertyInfo> piList = new List<PropertyInfo>();
            List<object> temp = new List<object>();
            //2.遍历成员属性信息表判断是否复用,添加到属性值缓存表
            foreach (PropertyInfo pi in list) {
                ZComponentToolsSettingsAttribute attr = ZAttrGetter.GetPropertyAttr(pi, typeof(ZComponentToolsSettingsAttribute)) as ZComponentToolsSettingsAttribute;
                if (attr.Reuse == true) {
                    piList.Add(pi);
                    temp.Add(pi.GetValue(this));
                }
            }
            //3.将 属性值缓存表中的值 重新 赋给 Tools 的 成员属性
            this.operationObject = obj;
            for (int i=0; i<temp.Count; i++) {
                try {
                    piList[i].SetValue(this, temp[i]);
                } catch (Exception) {

                }
            }
        }

        /// <summary>
        /// 重设Tools的设置
        /// </summary>
        public void ResetSettings() {
            this.operationObject = null;
            //1.取出对象中包含指令特性的成员属性
            List<PropertyInfo> list = ZAttrGetter.GetPropertyInfosConformAttribute(this, typeof(ZComponentToolsSettingsAttribute));
            List<PropertyInfo> piList = new List<PropertyInfo>();
            List<object> temp = new List<object>();
            //2.遍历成员属性信息表判断是否复用,添加到属性值缓存表
            foreach (PropertyInfo pi in list) {
                ZComponentToolsSettingsAttribute attr1 = ZAttrGetter.GetPropertyAttr(pi, typeof(ZComponentToolsSettingsAttribute)) as ZComponentToolsSettingsAttribute;
                DefaultValueAttribute attr2 = ZAttrGetter.GetPropertyAttr(pi, typeof(DefaultValueAttribute)) as DefaultValueAttribute;
                if (attr1.Reset == true) {
                    if (attr2 != null) {
                        piList.Add(pi);
                        temp.Add(attr2.Value);
                    }
                }
            }
            //3.将 属性值缓存表中的值 重新 赋给 Tools 的 成员属性
            for (int i = 0; i < temp.Count; i++) {
                try {
                    piList[i].SetValue(this, temp[i]);
                } catch (Exception) {

                }
            }
        }

        /// <summary>
        /// 加载Tools的设置
        /// </summary>
        /// <param name="obj"></param>
        public void LoadSettings(T obj) {
            //1.取出对象中包含指令特性的成员属性
            List<PropertyInfo> list = ZAttrGetter.GetPropertyInfosConformAttribute(this, typeof(ZComponentToolsSettingsAttribute));
            List<PropertyInfo> piList = new List<PropertyInfo>();
            List<object> temp = new List<object>();

            //2.遍历成员属性信息表判断是否加载,添加到属性值缓存表
            foreach (PropertyInfo pi in list) {
                ZComponentToolsSettingsAttribute attr = ZAttrGetter.GetPropertyAttr(pi, typeof(ZComponentToolsSettingsAttribute)) as ZComponentToolsSettingsAttribute;
                if (attr.Load == true) {
                    piList.Add(pi);
                    temp.Add(pi.GetValue(this));
                }
            }
            //3.将 属性值缓存表中的值 重新 赋给 Tools 的 成员属性
            this.operationObject = obj;
            for (int i = 0; i < temp.Count; i++) {
                try {
                    piList[i].SetValue(this, temp[i]);
                } catch (Exception) {

                }
            }
        }
    }

    /// <summary>
    /// 
    /// </summary>
    [AttributeUsage(AttributeTargets.All)]
    public class ZComponentToolsSettingsAttribute : Attribute {

        private bool load = false;
        private bool reuse = false;
        private bool reset = false;

        public ZComponentToolsSettingsAttribute(bool Load = false, bool Reuse = false, bool Reset = true) {
            this.load = Load;
            this.reuse = Reuse;
            this.reset = Reset;
        }

        /// <summary>
        /// 允许加载
        /// </summary>
        public bool Load {
            get {
                return this.load;
            }
            set {
                this.load = value;
            }
        }

        /// <summary>
        /// 复用
        /// </summary>
        public bool Reuse {
            get {
                return this.reuse;
            }
            set {
                this.reuse = value;
            }
        }

        /// <summary>
        /// 重设
        /// </summary>
        public bool Reset {
            get {
                return this.reset;
            }
            set {
                this.reset = value;
            }
        }
    }
}

Bootstrap框架使用拖拽插件Nestable

最近写个项目,前端页面需要使用拖拽功能,秉着不要重复造轮子的心态,在网上找到一个靠谱的插件Nestable,很好用。但在使用中依然发现了部分问题。最直观的一个就是当将一个dd-list中的所有dd-i...
  • u011832039
  • u011832039
  • 2016年03月23日 19:30
  • 7863

WPF-17行为(以控件在界面拖动为例)

行为并不是WPF中的核心的部分,是Expression Blend的设计特性。使用行为的地方,也是可以使用触发器取代的。不过行为使用起来也是有趣的,下面以一个简单的例子看看它的用法。 重写OnAtt...
  • yysyangyangyangshan
  • yysyangyangyangshan
  • 2013年05月21日 17:54
  • 5071

c# DEVexpress控件应用【winform】

1.xtraTabControl    TabPage的切换:xtraTabControl.SelectedTabPage = xtraTabControl.TabPages[index];  //i...
  • zr_wb
  • zr_wb
  • 2016年07月22日 16:04
  • 1945

DevExpress中关于GridControl控件的一些常用属性设置方法

using System; using System.Collections.Generic; using System.Linq; using System.Text; using DevExpre...
  • u011681409
  • u011681409
  • 2016年03月03日 22:44
  • 1660

窗口和控件闪烁解决方案

窗口和控件闪烁解决方案
  • chenlycly
  • chenlycly
  • 2015年12月22日 22:57
  • 1393

WebBrowser控件拖拽的实现

 WebBrowser 作为群众喜闻乐见的插件, 一直以好用难写而臭名昭著. 其海量的接口忙的众多死程序员乐不思蜀. 前些天正好需要在WebBrowser中实现文件的拖拽, 遇到一些问题, 后来解决了...
  • norsd
  • norsd
  • 2008年09月01日 04:17
  • 5752

C# winform DevExpress上传图片

实现功能如下图: 注明:此文使用的是DevExpress控件,winform 原生控件也是一样使用方法。1.点击选择图片按钮,功能为通过对话框选择要上传的文件,并将该文件在下面的PictureE...
  • Gary_888
  • Gary_888
  • 2017年04月17日 14:50
  • 1350

DevExpress使用教程:常用Winform界面封装+慧都控件网【申明:来源于网络】

DevExpress使用教程:常用Winform界面封装+慧都控件网【申明:来源于网络】DevExpress使用教程:常用Winform界面封装:https://www.evget.com/artic...
  • yearHeaven
  • yearHeaven
  • 2017年01月03日 23:14
  • 364

问题解决——Group Box控件遮挡其他控件

一开始我在写一个小例子,界面显示效果是右边的样子。后来打算用别的方法实现下逻辑,又写了一个小例子,结果界面显示效果却是左面的样子。 当我看到界面效果不一样时,当时我就不乐意了,因为我的属性设置都是一样...
  • wlsgzl
  • wlsgzl
  • 2014年07月22日 15:06
  • 3214

MFC控件使用大全

MFC控件使用大全
  • daoming1112
  • daoming1112
  • 2017年01月23日 23:41
  • 3191
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# DevExpress WinForm编程 针对一些控件重复度高的属性设置问题的解决方案
举报原因:
原因补充:

(最多只允许输入30个字)