2011-12-22 3 views
2

Следуя руководству, направленному на создание видеопроигрывателя, я адаптировал его для создания диапазона управления HTML5. Вот мой код:Пользовательский серверный контроль устанавливает свойства по умолчанию при обратной передаче

namespace CustomServerControls 
{ 
    [DefaultProperty("Text")] 
    [ToolboxData("<{0}:Range runat=server ID=Range1></{0}:Range>")] 
    public class Range : WebControl 
    { 
     public int Min { get; set; } 
     public int Max { get; set; } 
     public int Step { get; set; } 
     public int Value { get; set; } 

     protected override void RenderContents(HtmlTextWriter output) 
     { 
      output.AddAttribute(HtmlTextWriterAttribute.Id, this.ID); 
      output.AddAttribute(HtmlTextWriterAttribute.Width, this.Width.ToString()); 
      output.AddAttribute(HtmlTextWriterAttribute.Height, this.Height.ToString()); 

      if (Min > Max) 
       throw new ArgumentOutOfRangeException("Min", "The Min value cannot be greater than the Max Value."); 

      if (Value > Max || Value < Min) 
       throw new ArgumentOutOfRangeException("Value", Value, 
                 "The Value attribute can not be less than the Min value or greater than the Max value"); 

      if (Min != 0) 
       output.AddAttribute("min", Min.ToString()); 

      if (Max != 0) 
       output.AddAttribute("max", Max.ToString()); 

      if (Step != 0) 
       output.AddAttribute("step", Step.ToString()); 

      output.AddAttribute("value", Value.ToString()); 

      output.AddAttribute("type", "range"); 
      output.RenderBeginTag("input"); 
      output.RenderEndTag(); 

      base.RenderContents(output); 
     } 
    } 
} 

Как вы можете видеть, очень просто, и это работает, насколько возможность устанавливать индивидуальные свойства.

Если я сделаю сообщение, чтобы проверить, что такое текущее значение, элемент управления возвращает его свойства по умолчанию (0). Я предполагаю, что это вопрос в представлении. Кто-нибудь видит что-либо, чего я не вижу в приведенном выше коде, чтобы сделать это правильно?

Edit:

Я заметил это разметка визуализируется на странице:

<span id="Range1" style="display:inline-block;"> 
    <input id="Range1" min="1" max="100" value="5" type="range"> 
</span> 

который, очевидно, не так, я не хочу поверочного тег создан, и Безразлично контроля ввода У меня есть имя. Поэтому, когда я возвращаю сообщение, я не получаю никаких данных от элемента управления.

ответ

1

Попробуйте это:

[DefaultProperty("Value")] 
[ToolboxData("<{0}:Range runat=server />")] 
public class Range : WebControl, IPostBackDataHandler { 

    private static readonly object mChangeEvent = new object(); 

    public Range() : base(HtmlTextWriterTag.Input) { } 

    [Category("Events")] 
    public event EventHandler Change { 
     add { Events.AddHandler(mChangeEvent, value); } 
     remove { Events.RemoveHandler(mChangeEvent, value); } 
    } 

    [DefaultValue(0)] 
    public int Value { 
     get { return (int?)ViewState["Value"] ?? 0; } 
     set { ViewState["Value"] = value; } 
    } 

    protected override void AddAttributesToRender(HtmlTextWriter writer) { 
     base.AddAttributesToRender(writer); 

     // Add other attributes (Max, Step and value) 

     writer.AddAttribute(HtmlTextWriterAttribute.Value, Value.ToString()); 
     writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID); 
     writer.AddAttribute(HtmlTextWriterAttribute.Type, "range"); 
    } 

    protected virtual void OnChange(EventArgs e) { 
     if (e == null) { 
      throw new ArgumentNullException("e"); 
     } 

     EventHandler handler = Events[mChangeEvent] as EventHandler; 

     if (handler != null) { 
      handler(this, e); 
     } 
    } 

    #region [ IPostBackDataHandler Members ] 

    public bool LoadPostData(string postDataKey, NameValueCollection postCollection) { 
     int val; 

     if (int.TryParse(postCollection[postDataKey], out val) && val != Value) { 
      Value = val; 
      return true; 
     } 

     return false; 
    } 

    public void RaisePostDataChangedEvent() { 
     OnChange(EventArgs.Empty); 
    } 

    #endregion 

} 

Насколько сказал @VinayC вы должны использовать ViewState и ControlState (для критически важных данных) сохраняться ваши контроля. Кроме того, вы должны реализовать IPostBackDataHandler, чтобы восстановить последнее значение и поднять событие изменения, как вы можете видеть в предыдущем примере.

Update

[DefaultProperty("Value")] 
[ToolboxData("<{0}:Range runat=server />")] 
public class Range : WebControl, IPostBackEventHandler, IPostBackDataHandler { 

    [Category("Behavior")] 
    [DefaultValue(false)] 
    public bool AutoPostBack { 
     get { return (bool?)ViewState["AutoPostBack"] ?? false; } 
     set { ViewState["AutoPostBack"] = value; } 
    } 

    protected override void OnPreRender(EventArgs e) { 
     base.OnPreRender(e); 

     if (!DesignMode && AutoPostBack) { 

      string script = @" 
var r = document.getElementById('{0}'); 

r.addEventListener('mousedown', function (e) {{ 
    this.oldValue = this.value; 
}}); 

r.addEventListener('mouseup', function (e) {{ 
    if (this.oldValue !== this.value) {{ 
     {1}; 
    }} 
}});"; 

      Page.ClientScript.RegisterStartupScript(
       this.GetType(), 
       this.UniqueID, 
       string.Format(script, this.ClientID, Page.ClientScript.GetPostBackEventReference(new PostBackOptions(this))), 
       true); 
     } 
    } 

    #region [ IPostBackEventHandler Members ] 

    public void RaisePostBackEvent(string eventArgument) { 
     // If you need to do somthing on postback, derive your control 
     // from IPostBackEventHandler interface. 
    } 

    #endregion 

} 

Приведенный выше код показывает, как вы можете использовать ClientScriptManager.GetPostBackEventReference и IPostBackEventHandler реализовать простой AutoPostBack для вашего контроля диапазона.

+0

Это работает! Спасибо. –

+0

Можете ли вы показать мне или связать меня с веб-сайтом, объяснив, как я буду использовать автоматический пост для этого элемента управления? Я искал и не нашел то, что искал. –

+0

@Nick, Обновлено! –

0

Проблема в том, что ваши свойства (Min, Max, Step, Value) являются подкрепленными полем экземпляром - в ASP.NET, каждая страницу, и каждый экземпляр элемента управления на нем получают воссоздавали когда сообщения страницы назад. Поэтому каждый раз эти свойства будут иметь значения по умолчанию (или значения, которые вы можете установить во время разработки) - чтобы сохранить эти значения за пост-обратно, вам нужно вернуть свои свойства, используя состояние представления. Например:

public int Min 
{ 
    get 
    { 
     var value = ViewState["Min"]; 
     return null != value ? (int)value : 0; 
    } 
    set { ViewState["Min"] = value; } 
} 

Поскольку вид состояние может быть отключено, авторы управления могут также использовать состояние управления для резервного копирования их важных свойства (которые необходимы для управления для работы) - для использования государственного контроля, вам нужно override LoadControlState и SaveControlState методов.

Например (с использованием состояния управления):

public int Min { get; set; } 
public int Max { get; set; } 
public int Step { get; set; } 
public int Value { get; set; } 

protected override void OnInit(EventArgs e) 
{ 
    Page.RegisterRequiresControlState(this); // must for using control state 
    base.OnInit(e); 
} 

protected override object SaveControlState() 
{ 
    return new int[] { Min, Max, Step, Value }; 
} 

protected override void LoadControlState(object state) 
{ 
    var values = state as int[]; 
    if (null != values) 
    { 
     Min = values[0]; Max = values[1]; 
     Step = values[2]; Value = values[3]; 
    } 
} 
+0

Спасибо за ответ, см. Редактирование в моем вопросе. –

Смежные вопросы