TypeConverter in PropertyGrid & Datagrid

来源:互联网 发布:舒尔特训练软件 编辑:程序博客网 时间:2024/04/30 14:51

自定义TypeConverter:可以用在Propertygrid或者Datagrid中

1. public class UnitTypeConverter : TypeConverter

    {
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return true;
        }


        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return true;
        }


        public override Object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
        {
            if (context.PropertyDescriptor.PropertyType == typeof(double))
            {
                string str = value.ToString();
                double ret;
                if (double.TryParse(str, out ret))
                {
                    Validate(context, culture, ret);
                    return ret;
                }
                return null;
            }


            if (context.PropertyDescriptor.PropertyType == typeof(int))
            {
                string str = value.ToString();
                double ret;
                if (double.TryParse(str, out ret))
                {
                    Validate(context, culture, (int)ret);
                    return (int)ret;
                }
                return null;
            }
            else
            {
                var valueStr = value as string;
                double valueDouble;
                if (double.TryParse(valueStr, out valueDouble))
                {
                    valueStr = AppendUnitString(valueStr, context);
                }


                Validate(context, culture, valueStr);
                Object ret = Quantity.Parse(valueStr, context.PropertyDescriptor.PropertyType);


                return ret;
            }
        }


        protected virtual string AppendUnitString(string text, ITypeDescriptorContext context)
        {
            return text;
        }


        protected static object GetNewValue(object value, Type dstType)
        {
            object newValue;
            if (dstType.IsQuantity())
            {
                newValue = Quantity.Parse(value.ToString(), dstType);
            }
            else if (dstType.IsDouble())
            {
                newValue = double.Parse(value.ToString());
            }
            else if (dstType.IsInteger())
            {
                newValue = int.Parse(value.ToString());
            }
            else
            {
                newValue = value;
            }
            return newValue;
        }


        protected static void Validate(ITypeDescriptorContext context, CultureInfo culture, Object value)
        {
            var type = context.PropertyDescriptor.ComponentType;
            var propertyInfo = type.GetProperty(context.PropertyDescriptor.Name);


            if (propertyInfo != null)
            {
                object newValue = GetNewValue(value, propertyInfo.PropertyType);
                var validationAttributes = propertyInfo.GetAttributes<ValidationAttribute>();
                foreach (var validationAttribute in validationAttributes)
                {
                    if (!validationAttribute.IsValid(newValue))
                    {
                        string error = validationAttribute.FormatErrorMessage(propertyInfo.GetDescriptionName());
                        throw new NmcpException(error);
                    }
                }


                if (context.Instance is object[])
                {
                    var objs = context.Instance as object[];
                    foreach (object obj in objs)
                    {
                        ValidateInstance(obj, propertyInfo, newValue);
                    }
                }
                else
                {
                    ValidateInstance(context.Instance, propertyInfo, newValue);
                }
            }
        }


        private static void ValidateInstance(object obj, PropertyInfo propertyInfo, object newValue)
        {
            if (obj is IValidate)
            {
                object oldValue = propertyInfo.GetValue(obj, null);
                var validator = obj as IValidate;


                try
                {
                    propertyInfo.SetValue(obj, newValue, null);
                    validator.Validate();
                }
                finally
                {
                    propertyInfo.SetValue(obj, oldValue, null);
                }
            }
        }
    }

2.定义对象,属性(每个属性上apply TypeConverter),以及列表(for datagrid)

public class DieselEngineParameters
    {
        public DieselEngineParameters()
        {
            _comPressure = new Pressure(0);
            _maxPressure = new Pressure(0);
            MIP = new Pressure(0);
            SpeedMCR = new RotationalSpeed(0);
            PowerMCR = new RateOfEnergy(0);
            PowerPerCyl = new RateOfEnergy(0);
        }


        public Guid OID { get; set; }
        public double Load { get; set; }
        
        [TypeConverter(typeof(TvcTypeConverter)), TvcDisplayFormatAttribute(DisplayFormat = "F0")]
        public RotationalSpeed SpeedMCR { get; set; }


        [TypeConverter(typeof(TvcTypeConverter)), TvcDisplayFormatAttribute(DisplayFormat = "F1")]
        public Pressure MIP { get; set; }


        [TypeConverter(typeof(TvcTypeConverter)), TvcDisplayFormatAttribute(DisplayFormat = "F2")]
        public RateOfEnergy PowerMCR { get; set; }


        [TypeConverter(typeof(TvcTypeConverter)), TvcDisplayFormatAttribute(DisplayFormat = "F2")]
        public RateOfEnergy PowerPerCyl { get; set; }


        private Pressure _maxPressure;
        [TypeConverter(typeof(TvcTypeConverter)), TvcDisplayFormatAttribute(DisplayFormat = "F1")]
        public Pressure MaxPressure
        {
            get { return _maxPressure; }
            set
            {
                if (_maxPressure == value || value.Amount < 0 || value < ComPressure)
                {
                    return;
                }
                _maxPressure = value;
            }
        }


        private Pressure _comPressure;
        [TypeConverter(typeof(TvcTypeConverter)), TvcDisplayFormatAttribute(DisplayFormat = "F1")]
        public Pressure ComPressure
        {
            get { return _comPressure; }
            set
            {
                if (_comPressure == value || value.Amount < 0 || value > MaxPressure)
                {
                    return;
                }
                _comPressure = value;
            }
        }
    }


    public class LoadCaseDieselEngineParameters
    {
        public List<DieselEngineParameters> ListDieselEngineParameters { get; set; }


        public LoadCaseDieselEngineParameters()
        {
            ListDieselEngineParameters = new List<DieselEngineParameters>();
        }
    }


4. datagrid/databinding用法.

this.dgvGensetSettings.DataSource = this.gensetBindingSource;

gensetBindingSource.DataSource = new BindingList<DieselEngineParameters>(_lc.ListDieselEngineParameters.FindAll(t => t.OID == diesel.Oid));


Datagrid处理一些非法的输入

private void dgvGensetSettings_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            oldCellValue = dgvGensetSettings.CurrentCell.Value;
        }


Occurs when a cell leaves edit mode if the cell value has been modified.

private void dgvGensetSettings_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
        {
            if (e != null)
            {
                if (e.Value != null)
                {
                    try
                    {
                        e.Value = Quantity.Parse(e.Value.ToString(), e.DesiredType);
                    }
                    catch
                    {
                        e.Value = oldCellValue;
                    }
                    e.ParsingApplied = true;
                }
            }
        }


5. BindingSource.Filter fails when datasource derives from List(Of T)

不起作用;BindingSource只有为DataView或者实现了IBindingListView接口。Filter功能才气作用;

Please also make sure that you BindingSource is bound to a DataView or a data list which implements the IBindingListView interface. Like 

Code Snippet

    BindingSource bs1 = new BindingSource();   

    bs1.DataSource = myDataView;


原创粉丝点击