System.Web.UI.WebControls.Unit 的行为

Posted

技术标签:

【中文标题】System.Web.UI.WebControls.Unit 的行为【英文标题】:Behaviour of System.Web.UI.WebControls.Unit 【发布时间】:2017-09-18 13:38:18 【问题描述】:

我有一个asp:TextBox,我可以通过以下方式设置width

<asp:TextBox runat="server" ID="TextBox1" Width="100"></asp:TextBox>

<asp:TextBox runat="server" ID="TextBox1" Width="100%"></asp:TextBox>

在 Codebehind 中我只能设置

TextBox1.Width = 100; // remember, Width is type of Unit, not int

不可能是这样的:

TextBox1.Width = "100%"; 

我的期望

TextBox1.Width = new Unit.. ;

问题:为什么nUnit 会这样?为什么int 可能但string 不可能,为什么不期望Unit 的新对象?

【问题讨论】:

【参考方案1】:

你可以这样设置百分比。

TextBox1.Width = System.Web.UI.WebControls.Unit.Percentage(90);

【讨论】:

【参考方案2】:

TextBox 是一个WebControl,其中 Width 是一个虚拟属性,定义为:

    [DefaultValue(typeof(Unit), "")]
    [WebCategory("Layout")]
    [WebSysDescription("WebControl_Width")]
    public virtual Unit Width
    
        get
        
            if (!this.ControlStyleCreated)
            
                return Unit.Empty;
            
            return this.ControlStyle.Width;
        
        set
        
            this.ControlStyle.Width = value;
        
    

Unit 是一个结构(这是您问题的答案):

[Serializable]
[TypeConverter(typeof(UnitConverter))]
public struct Unit

    internal const int MaxValue = 32767;

    internal const int MinValue = -32768;

    public readonly static Unit Empty;

    private readonly UnitType type;

    private readonly double @value;

    public bool IsEmpty
    
        get
        
            return (int)this.type == 0;
        
    

    public UnitType Type
    
        get
        
            if (this.IsEmpty)
            
                return UnitType.Pixel;
            
            return this.type;
        
    

    public double Value
    
        get
        
            return this.@value;
        
    

    static Unit()
    
        Unit.Empty = new Unit();
    

    public Unit(int value)
    
        if (value < -32768 || value > 32767)
        
            throw new ArgumentOutOfRangeException("value");
        
        this.@value = (double)value;
        this.type = UnitType.Pixel;
    

    public Unit(double value)
    
        if (value < -32768 || value > 32767)
        
            throw new ArgumentOutOfRangeException("value");
        
        this.@value = (double)((int)value);
        this.type = UnitType.Pixel;
    

    public Unit(double value, UnitType type)
    
        if (value < -32768 || value > 32767)
        
            throw new ArgumentOutOfRangeException("value");
        
        if (type != UnitType.Pixel)
        
            this.@value = value;
        
        else
        
            this.@value = (double)((int)value);
        
        this.type = type;
    

    public Unit(string value) : this(value, CultureInfo.CurrentCulture, UnitType.Pixel)
    
    

    public Unit(string value, CultureInfo culture) : this(value, culture, UnitType.Pixel)
    
    

    internal Unit(string value, CultureInfo culture, UnitType defaultType)
    
        if (string.IsNullOrEmpty(value))
        
            this.@value = 0;
            this.type = (UnitType)0;
            return;
        
        if (culture == null)
        
            culture = CultureInfo.CurrentCulture;
        
        string lower = value.Trim().ToLower(CultureInfo.InvariantCulture);
        int length = lower.Length;
        int num = -1;
        for (int i = 0; i < length; i++)
        
            char chr = lower[i];
            if ((chr < '0' || chr > '9') && chr != '-' && chr != '.' && chr != ',')
            
                break;
            
            num = i;
        
        if (num == -1)
        
            object[] objArray = new object[]  value ;
            throw new FormatException(SR.GetString("UnitParseNoDigits", objArray));
        
        if (num >= length - 1)
        
            this.type = defaultType;
        
        else
        
            this.type = Unit.GetTypeFromString(lower.Substring(num + 1).Trim());
        
        string str = lower.Substring(0, num + 1);
        try
        
            TypeConverter singleConverter = new SingleConverter();
            this.@value = (double)((float)singleConverter.ConvertFromString(null, culture, str));
            if (this.type == UnitType.Pixel)
            
                this.@value = (double)((int)this.@value);
            
        
        catch
        
            object[] objArray1 = new object[]  value, str, this.type.ToString("G") ;
            throw new FormatException(SR.GetString("UnitParseNumericPart", objArray1));
        
        if (this.@value < -32768 || this.@value > 32767)
        
            throw new ArgumentOutOfRangeException("value");
        
    

    public override bool Equals(object obj)
    
        if (obj == null || !(obj is Unit))
        
            return false;
        
        Unit unit = (Unit)obj;
        if (unit.type == this.type && unit.@value == this.@value)
        
            return true;
        
        return false;
    

    public override int GetHashCode()
    
        return HashCodeCombiner.CombineHashCodes(this.type.GetHashCode(), this.@value.GetHashCode());
    

    private static string GetStringFromType(UnitType type)
    
        switch (type)
        
            case UnitType.Pixel:
            
                return "px";
            
            case UnitType.Point:
            
                return "pt";
            
            case UnitType.Pica:
            
                return "pc";
            
            case UnitType.Inch:
            
                return "in";
            
            case UnitType.Mm:
            
                return "mm";
            
            case UnitType.Cm:
            
                return "cm";
            
            case UnitType.Percentage:
            
                return "%";
            
            case UnitType.Em:
            
                return "em";
            
            case UnitType.Ex:
            
                return "ex";
            
        
        return string.Empty;
    

    private static UnitType GetTypeFromString(string value)
    
        if (string.IsNullOrEmpty(value))
        
            return UnitType.Pixel;
        
        if (value.Equals("px"))
        
            return UnitType.Pixel;
        
        if (value.Equals("pt"))
        
            return UnitType.Point;
        
        if (value.Equals("%"))
        
            return UnitType.Percentage;
        
        if (value.Equals("pc"))
        
            return UnitType.Pica;
        
        if (value.Equals("in"))
        
            return UnitType.Inch;
        
        if (value.Equals("mm"))
        
            return UnitType.Mm;
        
        if (value.Equals("cm"))
        
            return UnitType.Cm;
        
        if (value.Equals("em"))
        
            return UnitType.Em;
        
        if (!value.Equals("ex"))
        
            throw new ArgumentOutOfRangeException("value");
        
        return UnitType.Ex;
    

    public static bool operator ==(Unit left, Unit right)
    
        if (left.type != right.type)
        
            return false;
        
        return left.@value == right.@value;
    

    public static implicit operator Unit(int n)
    
        return Unit.Pixel(n);
    

    public static bool operator !=(Unit left, Unit right)
    
        if (left.type != right.type)
        
            return true;
        
        return left.@value != right.@value;
    

    public static Unit Parse(string s)
    
        return new Unit(s, CultureInfo.CurrentCulture);
    

    public static Unit Parse(string s, CultureInfo culture)
    
        return new Unit(s, culture);
    

    public static Unit Percentage(double n)
    
        return new Unit(n, UnitType.Percentage);
    

    public static Unit Pixel(int n)
    
        return new Unit(n);
    

    public static Unit Point(int n)
    
        return new Unit((double)n, UnitType.Point);
    

    public override string ToString()
    
        return this.ToString((IFormatProvider)CultureInfo.CurrentCulture);
    

    public string ToString(CultureInfo culture)
    
        return this.ToString((IFormatProvider)culture);
    

    public string ToString(IFormatProvider formatProvider)
    
        string str;
        if (this.IsEmpty)
        
            return string.Empty;
        
        str = (this.type != UnitType.Pixel ? ((float)this.@value).ToString(formatProvider) : ((int)this.@value).ToString(formatProvider));
        return string.Concat(str, Unit.GetStringFromType(this.type));
    

它定义了一个UnitConverter:

public class UnitConverter : TypeConverter

    public UnitConverter()
    
    

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    
        if (sourceType == typeof(string))
        
            return true;
        
        return base.CanConvertFrom(context, sourceType);
    

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    
        if (destinationType == typeof(string) || destinationType == typeof(InstanceDescriptor))
        
            return true;
        
        return base.CanConvertTo(context, destinationType);
    

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    
        if (value == null)
        
            return null;
        
        string str = value as string;
        if (str == null)
        
            return base.ConvertFrom(context, culture, value);
        
        string str1 = str.Trim();
        if (str1.Length == 0)
        
            return Unit.Empty;
        
        if (culture != null)
        
            return Unit.Parse(str1, culture);
        
        return Unit.Parse(str1, CultureInfo.CurrentCulture);
    

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    
        if (destinationType == typeof(string))
        
            if (value == null || ((Unit)value).IsEmpty)
            
                return string.Empty;
            
            return ((Unit)value).ToString(culture);
        
        if (destinationType != typeof(InstanceDescriptor) || value == null)
        
            return base.ConvertTo(context, culture, value, destinationType);
        
        Unit unit = (Unit)value;
        MemberInfo constructor = null;
        object[] objArray = null;
        if (!unit.IsEmpty)
        
            Type type = typeof(Unit);
            Type[] typeArray = new Type[]  typeof(double), typeof(UnitType) ;
            constructor = type.GetConstructor(typeArray);
            object[] objArray1 = new object[]  unit.Value, unit.Type ;
            objArray = objArray1;
        
        else
        
            constructor = typeof(Unit).GetField("Empty");
        
        if (constructor == null)
        
            return null;
        
        return new InstanceDescriptor(constructor, objArray);
    

在此代码中,您可以找到问题的答案。

【讨论】:

【参考方案3】:

Unit 是一个结构体,如果你的意思是Unit

试试 myUnit.Value。它将获得所指出的值。 您可以使用constructor 然后public Unit(int value) 转换回来。

我认为这应该会有所帮助。

【讨论】:

以上是关于System.Web.UI.WebControls.Unit 的行为的主要内容,如果未能解决你的问题,请参考以下文章

System.Web.UI.WebControls.Unit 的行为

System.Web.UI.WebControls.Image 不包含保存的定义?保存图像

获取 ASP.NET System.Web.UI.WebControls.PlaceHolder 的内容

将 varchar 值“System.Web.UI.WebControls.TextBox”转换为数据类型 int 时转换失败。

System.Web.UI.WebControls.TextBox”不包含“text”的定义,并且找不到可接受类型为“System.Web.UI.Web

仅对具有 DataBinding 事件的对象提供数据绑定表达式支持。System.Web.UI.WebControls.HyperLinkField 没