winform中propertygrid可用的动态属性

  1. 动态对象
// 动态对象实现
    [TypeConverter(typeof(CategoriesSortedByClassDefinitionConverter)), CategoriesSortedByClassDefinitionConverter.ElementsSameOrder]
    public class DynamicObject : ICustomTypeDescriptor
    {
        /// <summary>
        /// 项目的英文名称
        /// </summary>
        public string CustomName { set; get; }
        public object TagInfo { get; set; }

        // private PropertyCollection _properties = new PropertyCollection();
        private List<DynamicProperty> _properties = new List<DynamicProperty>();
        private List<string> _categoryList = new List<string>();

        public void AddProperty(string name, object value, string displayName = null, string description = null, string cateogry = "属性", bool readOnly = false, Type converterType = null, bool browsable = true, TypeConverter typeConverter = null)
        {
            _properties.Add(new DynamicProperty(name, value, displayName, description, cateogry, readOnly, converterType, browsable, typeConverter));
            if (!string.IsNullOrEmpty(cateogry) && !_categoryList.Contains(cateogry))
            {
                _categoryList.Add(cateogry);
            }
        }

        public object GetPropertyOwner(PropertyDescriptor pd) => this;

        /// <summary>
        /// 返回属性的集合
        /// </summary>
        /// <returns></returns>
        public PropertyDescriptorCollection GetProperties()
        {
            /*var visibleProperties = _properties.Where(p => p.IsBrowsable);
            return new PropertyDescriptorCollection(visibleProperties.ToArray());*/

            //return new PropertyDescriptorCollection(_properties.ToArray(), true);

            var arr = _properties.Where(x => x.IsBrowsable).ToArray();
            return new PropertyDescriptorCollection(arr, true);
        }

        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            return GetProperties();
            //return new PropertyDescriptorCollection(_properties.ToArray());
        }

        // ICustomTypeDescriptor 其他接口方法可以选择实现空逻辑
        public AttributeCollection GetAttributes() => AttributeCollection.Empty;
        public string GetClassName() => null;
        public string GetComponentName() => null;
        public TypeConverter GetConverter() => null;
        public EventDescriptor GetDefaultEvent() => null;
        public PropertyDescriptor GetDefaultProperty() => null;
        public object GetEditor(Type editorBaseType) => null;
        public EventDescriptorCollection GetEvents() => EventDescriptorCollection.Empty;
        public EventDescriptorCollection GetEvents(Attribute[] attributes) => EventDescriptorCollection.Empty;

        public List<DynamicProperty> GetDynamicProperties() => _properties;

        public DynamicProperty GetDynamicProperty(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return null;
            }

            DynamicProperty data = null;
            foreach (DynamicProperty tmp in _properties)
            {
                if (!tmp.Name.Equals(name))
                {
                    continue;
                }

                data = tmp;
                break;
            }

            return data;
        }

        public void SetPropertyReadonly(string name, bool isReadOnly)
        {
            foreach (var tmp in _properties)
            {
                if (!tmp.Name.Equals(name))
                {
                    continue;
                }

                tmp.CustomIsRreadOnly = isReadOnly;
                break;
            }
        }

        public void SetPropertyBrowse(string name, bool browse)
        {
            foreach (var tmp in _properties)
            {
                if (!tmp.Name.Equals(name))
                {
                    continue;
                }

                tmp.SetBrowse(browse);
                break;
            }
        }

        public void SetCustomConverter(string name, TypeConverter typeConverter)
        {
            foreach (var tmp in _properties)
            {
                if (!tmp.Name.Equals(name))
                {
                    continue;
                }

                tmp.CustomTypeConverter = typeConverter;
                break;
            }
        }

        public bool RemovePropertyByName(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return true;
            }

            DynamicProperty data = null;

            foreach (DynamicProperty tmp in _properties)
            {
                if (!tmp.Name.Equals(name))
                {
                    continue;
                }

                data = tmp;
                break;
            }

            _properties.Remove(data);

            return true;
        }
    }

2. 动态属性

// 动态属性类
    public class DynamicProperty : PropertyDescriptor
    {
        private object _value;
        private Type _converterType;
        private string _displayName;
        private string _category;
        private bool _brows;
        private string _desc;
        private bool _readOnly;
        private TypeConverter _typeConverter;

        public bool CustomIsRreadOnly { set; get; }

        public TypeConverter CustomTypeConverter { get => _typeConverter; set { _typeConverter = value; } }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="displayName">显示名称</param>
        /// <param name="description">描述</param>
        /// <param name="cateogry">分类</param>
        /// <param name="readlyOnly">只读</param>
        /// <param name="converterType">转换器</param>
        /// <param name="brows">显示</param>
        public DynamicProperty(string name, object value, string displayName = null, string description = null, string cateogry = "属性", bool readlyOnly = false, Type converterType = null, bool brows = true, TypeConverter typeConverter = null) : base(name, new Attribute[0])
        {
            _value = value;
            _converterType = converterType;
            _displayName = displayName;
            if (string.IsNullOrEmpty(displayName))
            {
                _displayName = name;
            }
            _category = cateogry;
            _brows = brows;
            _desc = description;
            _readOnly = readlyOnly;
            CustomIsRreadOnly = readlyOnly;
            _typeConverter = typeConverter;
        }

        public override bool CanResetValue(object component) => false;
        public override Type ComponentType => typeof(DynamicObject);
        public override object GetValue(object component) => _value;
        public override bool IsReadOnly => CustomIsRreadOnly;
        public override Type PropertyType => _value.GetType();
        public override void ResetValue(object component) { }
        public override void SetValue(object component, object value) => _value = value;
        public override bool ShouldSerializeValue(object component) => true;

        public override TypeConverter Converter
        {
            get
            {
                /*if (_value is bool)
                {
                    return new BooleanCheckBoxConverter();
                }*/
                if (_converterType != null)
                {
                    return (TypeConverter)Activator.CreateInstance(_converterType);
                }
                if (_typeConverter != null)
                {
                    return _typeConverter;
                }
                return base.Converter;
            }
        }

        public override string DisplayName => _displayName;

        public override string Category => _category;

        public override bool IsBrowsable => _brows;

        public override string Description => _desc;


        public override AttributeCollection Attributes
        {
            get
            {
                var attributes = base.Attributes.Cast<Attribute>().ToList();
                if (CustomIsRreadOnly)
                {
                    attributes.Add(new ReadOnlyAttribute(true));
                }

                return new AttributeCollection(attributes.ToArray());
            }
        }

        public void SetCategory(string newCategory)
        {
            _category = newCategory;
        }

        public void SetBrowse(bool val)
        {
            _brows = val;
        }
    }

3. 用法

DynamicObject gradeObj = new DynamicObject()
{
	CustomName = "YourName",
	TagInfo = tagInfo
};
gradeObj.AddProperty("Category", "三年级", "年级", "班级描述", "基本属性", true, null, true);
gradeObj.AddProperty("Type", "", "二班", "班级", "基本属性", true, null, true);
PropertyGrid.SelectedObject = gradeObj;

// 读取
DynamicObject customroperty = (DynamicObject)PropertyGrid.SelectedObject;
string catStr = customroperty.GetDynamicProperty("Category").GetValue("Category").ToString();

devexpress winform中,gridcontrol中rowdata的颜色修改

修改行数据的颜色,代码如下:

private void gridView1_RowStyle(object sender, RowStyleEventArgs e)
{
	if (e.RowHandle < 0)
	{
		return;
	}

	GridView v = sender as GridView;
	ProcessAlarmData rowData = v.GetRow(e.RowHandle) as ProcessAlarmData;
	if (rowData == null)
	{
		return;
	}

	e.Appearance.ForeColor = Color.Red;
	
	e.HighPriority = true;

	if (v.IsRowSelected(e.RowHandle) || e.RowHandle == v.FocusedRowHandle)
	{
		e.Appearance.BackColor = v.PaintAppearance.SelectedRow.BackColor;
	}
}

c# 执行exe

以下是代码:

Process process = new Process();
string exePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,  "a.exe");

string s = "";
foreach (var tmpArg in args)
{
	s += tmpArg.ToString() + " ";
}
s = s.Trim();
if (string.IsNullOrWhiteSpace(s))
{
	throw new Exception("缺少参数");
}

ProcessStartInfo psi = new ProcessStartInfo(exePath , s)
{
	CreateNoWindow = true,
	UseShellExecute = false,
};
process.StartInfo = psi;

process.Start();
process.WaitForExit();

winform datagridview 自动换行

1. 设置下DefaultCellStyle属性里的WrapMode属性,默认为false,设置为true。
2. 设置下AutoSizeRowsMode属性为:DisplayedCellsExceptHeaders。

补充,调整列宽:

在DataGridView的值设置为Fill的情况下调整列宽

dataGridView1.Columns[0].FillWeight = 10; //第一列的相对宽度为10%
dataGridView1.Columns[1].FillWeight = 30; //第二列的相对宽度为30%
dataGridView1.Columns[2].FillWeight = 70; //第三列的相对宽度为70%
注意:这里的值是相对于DataGridView当前的总宽度的.所以窗体最大化和缩小的效果是不一样的.但比例不变



另一种形式:让列固定宽度
dataGridView1.Columns[0].Width = 55;

c# dapper mysql like

const string sql = "SELECT * from user_profile WHERE FirstName LIKE @name;";
var result = connection.Query<Profile>(sql, new {name = "%"+name+"%"});

Linux配置.Net Core环境

  1. 安装.net sdk

执行命令sudo pacman -S dotnet-sdk(这里用的manjaro)

运行完后,运行dotnet --info 查看版本,显示如下,说明安装成功。

.NET Core SDK (reflecting any global.json):
 Version:   2.2.102
 Commit:    96ff75a873

Runtime Environment:
 OS Name:     manjaro
 OS Version:  
 OS Platform: Linux
 RID:         arch-x64
 Base Path:   /opt/dotnet/sdk/2.2.102/

Host (useful for support):
  Version: 2.2.1
  Commit:  878dd11e62

.NET Core SDKs installed:
  2.2.102 [/opt/dotnet/sdk]

.NET Core runtimes installed:
  Microsoft.NETCore.App 2.2.1 [/opt/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download

2. 创建项目

执行命令 dotnet new web -o web 这句命令的意思是,创建一个ASP. NET Core Empty项目,并将该项目命名为web,显示一下信息说明项目创建成功

The template "ASP.NET Core Empty" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on weba/web.csproj...
  Restoring packages for /home/txl/csharp/weba/web.csproj...
  Generating MSBuild file /home/txl/csharp/weba/obj/web.csproj.nuget.g.props.
  Generating MSBuild file /home/txl/csharp/weba/obj/web.csproj.nuget.g.targets.
  Restore completed in 2.3 sec for /home/txl/csharp/web/web.csproj.

Restore succeeded.

3. 运行项目

运行dotnet build  命令,先编译下项目

Microsoft (R) Build Engine version 15.9.20.63311 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 609.99 ms for /home/txl/csharp/weba/weba.csproj.
  webtestapi -> /home/txl/csharp/weba/bin/Debug/netcoreapp2.2/weba.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:03.70

在运行项目,dotnet run

第一运行时可能会出现错误:

info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
      User profile is available. Using '/home/txl/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
crit: Microsoft.AspNetCore.Server.Kestrel[0]
      Unable to start Kestrel.
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
   at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)

Unhandled Exception: System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
   at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
   at webtestapi.Program.Main(String[] args) in /home/txl/csharp/weba/Program.cs:line 17

这个错误说明要安装一个证书,开启https,错误中已经给出提示,如果是linux系统,执行dotnet dev-certs https 命令。

如果是windows或mac系统,执行`dotnet dev-certs https –trust`。

运行dotnet dev-certs https, 出现以下问题。

Cannot find command 'dotnet dev-certs', please run the following command to install

dotnet tool install --global dotnet-dev-certs

所以,又执行dotnet tool install --global dotnet-dev-certs 命令,却又出现这个…

Tool 'dotnet-dev-certs' is already installed.

这里查了好久,发现dotnet-dev-certs是一个执行文件,位于$HOME/.dotnet/tools目录下,所以执行$HOME/.dotnet/tools/dotnet-dev-certs https,本以为没问题,结果又出现

A fatal error occurred, the required library libhostfxr.so could not be found.
If this is a self-contained application, that library should exist in [/home/txl/.dotnet/tools/.store/dotnet-dev-certs/2.2.0/dotnet-dev-certs/2.2.0/tools/netcoreapp2.2/any/].
If this is a framework-dependent application, install the runtime in the default location [/usr/share/dotnet] or use the DOTNET_ROOT environment variable to specify the runtime location.

到这里,真是有点崩溃了,于是再找之,发现需要设置环境变量DOTNET_ROOT

设置环境变量export DOTNET_ROOT=/opt/dotnet,这个目录是不是很眼熟,没错,

就是dotnet --info命令中的Bash Path的前半段。

然后在在执行命令$HOME/.dotnet/tools/dotnet-dev-certs https

The HTTPS developer certificate was generated successfully.

ok,终于看到希望了,再执行dotnet run ,成功!

项目发布,发布目标平台为linux x64,并且包含dotent 运行时,这意味着目标服务器可以不用装dotnet 环境也可以运行

dotnet publish -c Release -r linux-x64 --self-contained true

Couldn’t find a valid ICU package installed on the system

今天安装了.net core sdk,使用命令`dotnet –info`,出现错误

FailFast:
Couldn't find a valid ICU package installed on the system. Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support.

   at System.Environment.FailFast(System.String)
   at System.Globalization.GlobalizationMode.GetGlobalizationInvariantMode()
   at System.Globalization.GlobalizationMode..cctor()
   at System.Globalization.CultureData.CreateCultureWithInvariantData()
   at System.Globalization.CultureData.get_Invariant()
   at System.Globalization.CultureInfo..cctor()
   at System.StringComparer..cctor()
   at System.AppDomain.InitializeCompatibilityFlags()
   at System.AppDomain.Setup(System.Object)
已放弃 (核心已转储)

于是发现,系统没有安装icu,遂安装之,`pacman -S icu`

再执行`dotnet –info`

.NET Core SDK (reflecting any global.json):
 Version:   2.2.102
 Commit:    96ff75a873

Runtime Environment:
 OS Name:     manjaro
 OS Version:  
 OS Platform: Linux
 RID:         arch-x64
 Base Path:   /opt/dotnet/sdk/2.2.102/

Host (useful for support):
  Version: 2.2.1
  Commit:  878dd11e62

.NET Core SDKs installed:
  2.2.102 [/opt/dotnet/sdk]

.NET Core runtimes installed:
  Microsoft.NETCore.App 2.2.1 [/opt/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download

成功!

.Net获取配置信息

做开发时,需要读取配置文件信息。.Net项目已经有配置文件,比如:Web.config,App.config,要读取这些配置文件里的信息,需要引用`System.Configuration`

以appSettings为例,使用`System.Configuration.ConfigurationManager.AppSettings[keyName] ` 即可获取配置信息