系统提供的WebControl基类里面没有有关位置的属性,但完成后在设计界面中拖动就会产生形如:
style="POSITION:absoulte;TOP:50px;LEFT:50px"字样,但这个属性不能在后台编码中设置,我重写了Style类,填加了top和left两个属性,重写WebControl的ControlStyle中处理,这时会产生这样的情况,会产生两个top和left属性,都在style中出现,但我设置的在最前面,系统自动产生的在后面,我的设置总不起作用。不知道怎么样控件设计界面中产生的那个位置属性。因为我想在后台编码中控制控件的位置。
各位帮帮忙啊,焦头烂额了。
下面是部分代码:exStyle继承Style的代码:using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace FormSystem.WebControl.ExWebControl
{
/// <summary>
/// exStyle 的摘要说明。
/// </summary>
/// 
public class exStyle:Style
{
/// <summary>
/// 判断是属性值是否已经设置
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
internal bool IsSet(Key k)
{
string er=null;
switch(k)
{
case Key.Left:
er="Left";
break;
case Key.Top:
er="Top";
break;
case Key.Position:
er="Position";
break;
default:
throw new ArgumentOutOfRangeException("Key");
}
if(er!=null)
{
return this.ViewState[er]!=null;
}
return false;
}
/// <summary>
/// 控件Y坐标
/// </summary>
public Unit Top
{
get
{
if (IsSet(Key.Top))
{
return (Unit) this.ViewState["Top"];
}
return Unit.Empty;
}
set
{
if (value.Value < 0)
{
throw new ArgumentOutOfRangeException("value");
}
this.ViewState["Top"] = value;
} }
public Unit Left
{
get
{
if (IsSet(Key.Left))
{
return (Unit) this.ViewState["Left"];
}
return Unit.Empty;
}
set
{
if (value.Value < 0)
{
throw new ArgumentOutOfRangeException("value");
}
this.ViewState["Left"] = value;

} }
public ControlPosition Position
{
get
{
if(IsSet(Key.Position))
{
return (ControlPosition)this.ViewState["Position"];
}
return ControlPosition.empty; }
set
{
if(value!=ControlPosition.absolute&&value!=ControlPosition.noset&&value!=ControlPosition.relative&&value!=ControlPosition.empty)
{
throw new ArgumentOutOfRangeException("value");
}
this.ViewState["Position"]=value;
}
}
protected new internal bool IsEmpty
{
get
{
return base.IsEmpty&&!IsSet(Key.Left)&&!IsSet(Key.Top)&&!IsSet(Key.Position);
}
}
public override void AddAttributesToRender(HtmlTextWriter writer, System.Web.UI.WebControls.WebControl owner)
{

if(IsSet(Key.Top))
{
writer.AddStyleAttribute("TOP",Top.ToString());
}
if(IsSet(Key.Left))
{
writer.AddStyleAttribute("LEFT",Left.ToString());
}
if(IsSet(Key.Position))
{
writer.AddStyleAttribute("POSITION",Position.ToString());
}
base.AddAttributesToRender (writer, owner);
}
public override void CopyFrom(Style s)
{
base.CopyFrom (s);
if(s is exStyle)
{
exStyle es=(exStyle)s;
if(!es.IsEmpty)
{
if(es.IsSet(Key.Left))
{
this.Top=es.Left;
}
if(es.IsSet(Key.Top))
{
this.Top=es.Top;
}
if(es.IsSet(Key.Position))
{
this.Position=es.Position;
}
}
}
}
public override void MergeWith(Style s)
{
if(s!=null)
{
if(IsEmpty)
{
CopyFrom(s);
return;
}
}
base.MergeWith (s);
if(s is exStyle)
{
exStyle es=(exStyle)s;
if(!es.IsEmpty)
{
if(es.IsSet(Key.Left)&&this.IsSet(Key.Left))
{
this.Left=es.Left;
}
if(es.IsSet(Key.Top)&&this.IsSet(Key.Top))
{
this.Top=es.Top;
}
if(es.IsSet(Key.Position)&&this.IsSet(Key.Position))
{
this.Position=es.Position;
}
}
}
}
public override void Reset()
{
base.Reset();
if(IsEmpty)
{
return;
}
if(IsSet(Key.Top))
ViewState.Remove("Top");
if(IsSet(Key.Left))
ViewState.Remove("Left");
if(IsSet(Key.Position))
ViewState.Remove("Position");
}
public exStyle()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public exStyle(StateBag bag):base(bag)
{

}
}
}
下面是设计的一个基控件继承自WebControl的代码,作为其他控件的基础。
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;namespace FormSystem.WebControl.ExWebControl
{
public enum Key{Top,Left,Position}
public enum ControlPosition{empty,noset,absolute,relative}
public enum BoxType{single,multiplicity,password}
public enum PositionStyle{Top,Left,Bottom,Right}
public enum AlignStyle
{lefttop,leftmiddle,leftbottom,centertop,centermiddle,centerbottom,righttop,rightmiddle,rightbottom}
/// <summary>
/// ControlBase 的摘要说明。
/// 所有自定义web控件的基类,继承自WebContrl,实现控件基本属性
/// 如:top,left等,并继承INamingContainer接口。
/// </summary>
[DefaultProperty("Text"), 
ToolboxData("<{0}:ControlBase runat=server></{0}:ControlBase>")]
public class ControlBase : System.Web.UI.WebControls.WebControl,INamingContainer
{
/// <summary>
/// 实现属性Top指控件Y坐标.
/// </summary>
[Bindable(true), 
Category("扩展属性"),
Description("控件左上角Y坐标"),
DefaultValue("0")]
public Unit Top
{
get
{
if(this.ControlStyleCreated)
{
return ((exStyle)ControlStyle).Top;
}
return Unit.Empty;
}
set
{
((exStyle)ControlStyle).Top=value;
}
}
/// <summary>
/// 实现属性Top指控件X坐标.
/// </summary>
[Bindable(true), 
Category("扩展属性"), 
Description("控件左上角X坐标"),
DefaultValue("0")]
public Unit Left
{
get
{
if(this.ControlStyleCreated)
{
return ((exStyle)ControlStyle).Left;
}
return Unit.Empty;
}
set
{
((exStyle)ControlStyle).Left=value;
}
}
/// <summary>
/// 实现属性Position指控件布局方式.
/// </summary>
[Bindable(true), 
Category("扩展属性"), 
Description("控件布局方式"),
DefaultValue("0")]
public ControlPosition Position
{
get
{
if(this.ControlStyleCreated)
{
return ((exStyle)ControlStyle).Position;
}
return ControlPosition.empty;
}
set
{
((exStyle)ControlStyle).Position=value;
}
}
public override ControlCollection Controls
{
get
{
this.EnsureChildControls();
return base.Controls;
}
}
protected override Style CreateControlStyle()
{
return new exStyle(ViewState);
} }
}

解决方案 »

  1.   

    下面是一个自定义控件代码,只是简单的label扩展控件。他继承ControlBase;
    using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.ComponentModel;namespace FormSystem.WebControl.ExWebControl
    {
    /// <summary>
    /// exLable 的摘要说明。
    /// </summary>
    [DefaultProperty("Text"), 
    ToolboxData("<{0}:exLable runat=server></{0}:exLable>")]
    public class exLable : ControlBase
    {
    private Label lb; [Bindable(true), 
    Category("扩展属性"), 
    DefaultValue(AlignStyle.centermiddle),
    Description("文字布局方式")]
    public AlignStyle TextAlign
    {
    get
    {
    object o=ViewState["TextAlign"];
    return (o==null)?AlignStyle.centermiddle:(AlignStyle)o;
    }
    set
    {
    if(value!=AlignStyle.centerbottom&&
    value!=AlignStyle.centermiddle&&
    value!=AlignStyle.centertop&&
    value!=AlignStyle.leftbottom&&
    value!=AlignStyle.leftmiddle&&
    value!=AlignStyle.lefttop&&
    value!=AlignStyle.rightbottom&&
    value!=AlignStyle.rightmiddle&&
    value!=AlignStyle.righttop
    )
    {
    throw new ArgumentOutOfRangeException("参数必须为AlignStyle枚举之一");
    }
    ViewState["TextAlign"]=value;
    }
    }
    [Bindable(true),
    Category("扩展属性"),
    Description("文本区域距左外边框距离"),
    DefaultValue(1)]
    public Unit LeftMargin
    {
    get
    {
    object o=ViewState["LeftMargin"];
    return (o==null)?1:(Unit)o;
    }
    set
    {
    if(value.Value<0)
    {
    throw new ArgumentOutOfRangeException("值不能小于0");
    }
    ViewState["LeftMargin"]=value;
    }
    }
    [Bindable(true),
    Category("扩展属性"),
    Description("文本区域距右外边框距离"),
    DefaultValue(1)]
    public Unit RightMargin
    {
    get
    {
    object o=ViewState["RightMargin"];
    return (o==null)?1:(Unit)o;
    }
    set
    {
    if(value.Value<0)
    {
    throw new ArgumentOutOfRangeException("值不能小于0");
    }
    ViewState["RightMargin"]=value;
    }
    }
    [Bindable(true),
    Category("扩展属性"),
    Description("文本区域距上外边框距离"),
    DefaultValue(1)]
    public Unit TopMargin
    {
    get
    {
    object o=ViewState["TopMargin"];
    return (o==null)?1:(Unit)o;
    }
    set
    {
    if(value.Value<0)
    {
    throw new ArgumentOutOfRangeException("值不能小于0");
    }
    ViewState["TopMargin"]=value;
    }
    }
    [Bindable(true),
    Category("扩展属性"),
    Description("文本区域距下外边框距离"),
    DefaultValue(1)]
    public Unit BottomMargin
    {
    get
    {
    object o=ViewState["BottomMargin"];
    return (o==null)?1:(Unit)o;
    }
    set
    {
    if(value.Value<0)
    {
    throw new ArgumentOutOfRangeException("值不能小于0");
    }
    ViewState["BottomMargin"]=value;
    }
    }
    [Bindable(true),
    Category("扩展属性"),
    Description("文本内容"),
    DefaultValue("")]
    public string Text
    {
    get
    {
    this.EnsureChildControls();
    return lb.Text;
    }
    set
    {
    this.EnsureChildControls();
    lb.Text=value;
    }
    }
    protected override void CreateChildControls()
    {
    base.CreateChildControls ();
    lb=new Label();
    this.Controls.Add(lb);
    lb.Text=Text;
    } /// <summary> 
    /// 将此控件呈现给指定的输出参数。
    /// </summary>
    /// <param name="output"> 要写出到的 HTML 编写器 </param>
    protected override void RenderContents(HtmlTextWriter writer)
    {
    this.AddAttributesToRender(writer);
    writer.AddAttribute(HtmlTextWriterAttribute.Border,"1");
    //writer.AddAttribute(HtmlTextWriterAttribute.Style,"Z-INDEX: 101; LEFT: "+(this.Left.Value+this.LeftMargin.Value)+"px; POSITION: absolute; TOP: "+(this.Top.Value+this.TopMargin.Value)+"px");
    writer.AddAttribute(HtmlTextWriterAttribute.Width,this.Width.ToString());
    writer.RenderBeginTag(HtmlTextWriterTag.Table);
    writer.RenderBeginTag(HtmlTextWriterTag.Tr);
    writer.AddAttribute(HtmlTextWriterAttribute.Width,this.Width.ToString());
    writer.RenderBeginTag(HtmlTextWriterTag.Td);
    lb.RenderControl(writer);
    writer.RenderEndTag();
    writer.RenderEndTag();
    writer.RenderEndTag();
    } }
    }
    不知道怎么才能在后台编码中设置自定义控件的位置属性?
      

  2.   

    原来的那个Left/Top是由于你设置了页面Grid布局风格后出现的,试着改成Flow布局,其实你也可以用Style["left"], Style["top"]设置,如果你要按你的方式做,可以试着重载AddAttributesToRender