dotNET
dotNET

Reputation: 35470

How to add a bindable property in my user control?

So I created an ASP.NET user control that is a simple wrapper around the bootstrap slider control. Now I want my control to have a public property named Value that I could bind to a property of my model, just like I do with asp:TextBox:

<asp:TextBox runat="server" Text="<%# BindItem.Name %>" />

Can I do the same with my user control?

<uc1:Slider runat="server" Value="<%# BindItem.Age %>" />

Upvotes: 0

Views: 1037

Answers (1)

dotNET
dotNET

Reputation: 35470

So for any future reader, here's a working version of bootstrap-slider's server-side control. You can drag-n-drop it onto your ASPX page. It has two properties Value and Value2 (for ranges). There is an event ValueChanged that will fire when user moves the position of slider. You can attach an event handler to this even just like you do for Button control's Click event. Last but not the least, I ensured that the control works within UpdatePanel too:

N.B. This control doesn't try to include the require JS or CSS file, because if user drops multiple instances of the Slider on the page, the output will probably include a copy of CSS and JS file for each instance, which is undesirable. I couldn't figure out how to link a CSS/JS file only if it hasn't already been included in the current page. So just make sure you include those two files in the parent page once for all.

Markup

<div id="<%= this.UniqueID + "_Div" %>">
    <input runat="server" ID="_TextBox" 
        EnableTheming="false" 
        class="slider form-control" 
        style="vertical-align: middle; width: 100%;" 
        data-slider-min="<%# Min %>" 
        data-slider-max="<%# Max %>"
        data-slider-step="<%# Step %>" 
        data-slider-value="<%# Value %>"
        data-slider-precision="<%# Precision %>" 
        data-slider-orientation="horizontal"
        data-slider-selection="after" 
        data-slider-tooltip="show"
        data-slider-range="<%# IsRange.ToString().ToLower() %>" />
</div>

Code-behind

using System;
using System.ComponentModel;
using System.Web.UI;

namespace YourProjectNameSpace
{
    public partial class Slider : System.Web.UI.UserControl
    {
        public bool IsRange { get; set; }
        public float Min { get; set; }
        public float Max { get; set; }
        public float Step { get; set; }
        public int Precision { get; set; }

        public event Action ValueChanged;

        [Bindable(true, BindingDirection.TwoWay)]
        public float Value
        {
            get 
            {
                if (IsRange)
                {
                    string[] Vals = (this._TextBox.Attributes["value"] ?? "0,0").Split(',');
                    return float.Parse(Vals[0]);
                }
                else
                    return float.Parse((this._TextBox.Attributes["value"] ?? "0"));
            }

            set
            {
                if (IsRange)
                {
                    string[] CurVals = (this._TextBox.Attributes["value"] ?? "0,0").Split(',');
                    this._TextBox.Attributes["value"] = value.ToString() + ',' + CurVals[1];
                }
                else
                    this._TextBox.Attributes["value"] = value.ToString();
            }
        }

        [Bindable(true, BindingDirection.TwoWay)]
        public float? Value2
        {
            get
            {
                if (IsRange)
                {
                    string[] Vals = (this._TextBox.Attributes["value"] ?? "0,0").Split(',');
                    return float.Parse(Vals[1]);
                }
                else
                    return null;
            }

            set
            {
                if (IsRange)
                {
                    string[] CurVals = (this._TextBox.Attributes["value"] ?? "0,0").Split(',');
                    this._TextBox.Attributes["value"] = CurVals[0] + ',' + value.ToString();
                }
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                if (Request["__EVENTTARGET"] == "_TextBox")
                {
                    if (ValueChanged != null)
                        ValueChanged();

                    string MyDivName = this.UniqueID.Replace("$", @"\\$") + "_Div";
                    string SliderVal = Request["__EVENTARGUMENT"];
                    if (IsRange) SliderVal = '[' + SliderVal.Split(',')[0] + ',' + SliderVal.Split(',')[1] + ']';

                    Page.ClientScript.RegisterStartupScript(this.GetType(), "CreateSliderFor_" + MyDivName,
                    "$('#" + MyDivName + " > input').slider().slider('setValue', " +  SliderVal + 
                    ").on('slideStop', function(slideEvt) { __doPostBack('_TextBox', slideEvt.value); });", true);
                }
                else
                {
                    string MyDivName = this.UniqueID.Replace("$", @"\\$") + "_Div";
                    Page.ClientScript.RegisterStartupScript(this.GetType(), "CreateSliderFor_" + MyDivName, "$('#" + MyDivName + " > input').slider().on('slideStop', function(slideEvt) { __doPostBack('_TextBox', slideEvt.value); });", true);
                }
            }
            else
            {
                string MyDivName = this.UniqueID.Replace("$", @"\\$") + "_Div";
                Page.ClientScript.RegisterStartupScript(this.GetType(), "CreateSliderFor_" + MyDivName, "$('#" + MyDivName + " > input').slider().on('slideStop', function(slideEvt) { __doPostBack('_TextBox', slideEvt.value); });", true);
            }

        }
    }
}    

Usage

Put this at the top of the page, after @Page line:

<%@ Register Src="~/Slider.ascx" TagPrefix="uc1" TagName="Slider" %>

Now place Slider control anywhere in the page:

<uc1:Slider runat="server" ID="Slider1" Min="10" Max="24" Value="<%# BindItem.Age %>" Step="0.1" Precision="1" IsRange="true" OnValueChanged="Slider1_ValueChanged" />

The event handler looks like this:

 protected void Slider1_ValueChanged()
 {
      //do whatever you want with Slider1.Value or Slider1.Value2
 }

Upvotes: 1

Related Questions