lincolnk
lincolnk

Reputation: 11238

how do I map an asp.net user control property to a server control within it?

I have a user control with a WebDateTimeEdit server control on it (essentially a TextBox). I'd like to be able to set some of the server control's properties by way of the user control's markup or programatically. for example I have this defined on my user control:

public string CssClass
{
    get { return this.WebDateTimeEdit1.CssClass; }
    set { this.WebDateTimeEdit1.CssClass = value; }
}

which allows me to do

<uc1:MyControl ID="MyControl1" runat="server" CssClass="fancycss"  />

and this works. but if I want to add a control through code,

MyControl myControl2 = new MyControl();
MyControl.CssClass = "fancycss";

this blows up because WebDateTimeEdit1 is null.

is there any way I can make this happen? also can do I do this

myControl2 .Font.Size = FontUnit.Point(8);

where the Font property is read only on the server control?

Upvotes: 1

Views: 812

Answers (2)

Doug
Doug

Reputation: 5318

The issue you are facing is due to the fact that web controls by nature are stateless. You need to persist the value of the properties you are setting so they are accessable between postbacks. Below is an example that implements asp.net viewstate.

So for example to enable state and avoid the null condition you are experienceing with the CssClass property of your custom control you can implement the propery as follows.

private string CssClass
{
  get
  {
    return (string)ViewState["cssclass"];
  }
  set
  {
    ViewState["cssclass"] = value;
  }
}

I have included a sample user control I wrote recently that will give you a model to work from.

    using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace Pdc.EventPro.WebControls
{
  [DefaultProperty("Text"), ToolboxData("<{0}:AnchorDomain1 runat=server></{0}:AnchorDomain1>")]
  public class AnchorDomain : Control
  {
    private string _href = string.Empty;

    public AnchorDomain()
    {
      VirtualPath = HttpContext.Current.Request.Path.Substring(0, HttpContext.Current.Request.Path.LastIndexOf("/") + 1);
    }

    private string VirtualPath
    {
      get
      {
        return (string)ViewState["virtualPath"];
      }
      set
      {
        ViewState["virtualPath"] = value;
      }
    }

    [Bindable(true), Category("Content"), DefaultValue("Performance Development Corporation")]
    public string Title
    {
      get
      {
        return (string)ViewState["title"];
      }

      set
      {
        ViewState["title"] = value;
      }
    }

    [Bindable(true), Category("Content"), DefaultValue("")]
    public string LinkText
    {
      get
      {
        return (string)ViewState["linktext"];
      }

      set
      {
        ViewState["linktext"] = value;
      }
    }

    [Bindable(true), Category("Content"), DefaultValue("")]
    public string Url
    {
      get
      {
        return (string)ViewState["url"];
      }

      set
      {
        ViewState["url"] = value;
      }
    }

    [Bindable(true), Category("Content"), DefaultValue("false")]
    public bool UsePageVirtualPath
    {
      get
      {
        return (bool)ViewState["useVirtualPath"];
      }

      set
      {
        ViewState["useVirtualPath"] = value;
      }
    }

    [Bindable(true), Category("Content"), DefaultValue("false")]
    public string CssClass
    {
      get
      {
        return (string)ViewState["CssClass"];
      }

      set
      {
        ViewState["CssClass"] = value;
      }
    }

    protected override void Render(HtmlTextWriter writer)
    {
      if (string.IsNullOrEmpty(Url) && UsePageVirtualPath == false)
      {
        _href = CreateUri(HttpContext.Current.Request.Url.GetLeftPart(System.UriPartial.Authority), HttpContext.Current.Request.ApplicationPath).ToString();
      }
      else if (!string.IsNullOrEmpty(Url) && UsePageVirtualPath == true)
      {
        _href = CreateUri(HttpContext.Current.Request.Url.GetLeftPart(System.UriPartial.Authority), CombineUri(VirtualPath, Url)).ToString();
      }
      else
      {
        _href = CreateUri(HttpContext.Current.Request.Url.GetLeftPart(System.UriPartial.Authority), CombineUri(HttpContext.Current.Request.ApplicationPath, Url)).ToString();
      }

      writer.WriteBeginTag("a");
      writer.WriteAttribute("href", _href);
      writer.WriteAttribute("title", Title);
      writer.WriteAttribute("class", CssClass);
      writer.Write(HtmlTextWriter.TagRightChar);
      writer.Write(LinkText);
      writer.WriteEndTag("a");

      base.Render(writer);
    }

    private Uri CreateUri(string baseUri, string relativeUri)
    {
      Uri result = null;

      if (Uri.TryCreate(new Uri(baseUri), relativeUri, out result))
      {
        return result;
      }

      return result;
    }

    private string CombineUri(string basePath1, string basePath2)
    {
      return string.Format("{0}/{1}", basePath1.TrimEnd('/'), basePath2.TrimStart('/')); 
    }
  }
}

Enjoy!

Upvotes: 0

Matt Greer
Matt Greer

Reputation: 62057

It depends on how your control is defined (is it a CompositeControl?), But generally speaking, you want to call EnsureChildControls() as the first line of the setter (and likely the getter too)

Upvotes: 1

Related Questions