Paging and the Entity Framework, Skip, and Take Part 4

Get the total count of pages. | Get the real page number. | Using Skip and Take to Page | The Actual Paging Controls

Now onto the fourth part of this epic saga that George Washington once called, “The most astounding exercise in futility”

Ok so let’s say you have a grid, items to fill it with, and four buttons. Each button has a direction, say one back, all the way back, one forward, all the way forward. No big deal. Now you want them to page correctly when used. After all, it’s always a bonus when things go right. First you need to set the CommandArguments on the buttons themselves to whatever page they are responsible for.

private void SetAndBind(Int32 pageNumber)
{
  Int32 realPage;
  Int32 totalCount;

  IList<ToolItem> inviteList =
    ToolClass
    .GetSomeTools("Sean", 20, pageNumber, out realPage, out totalCountOfPages);

  btnFullBack.CommandArgument = Convert.ToString(0);
  btnOneBack.CommandArgument = Convert.ToString(realPage - 1);
  btnOneForward.CommandArgument = Convert.ToString(realPage + 1);
  btnFullForward.CommandArgument = Convert.ToString(totalCountOfPages);

  BindGrid(inviteList);
}

First off, GetSomeTools is just a method that is the same as I presented in the third installment of this epic saga that George Washington once called, “The most astounding exercise in futility”. If you’ve been reading up to this point, then you’ll know that. If not, you might have some reading to do.

So, here’s a simple method used to get the info we need (using the page number) and set the buttons. As seen before, realPage is the actual possible page (In case someone passed in page 21 when there are only 20 pages) and totalCountOfPages gives us how many possible pages there are. This makes setting the button CommandArguments cake. Now for the button event:

  private void btnPaging_Click(Object sender, EventArgs e)
  {
    SetAndBind(Convert.ToInt32(((Button)sender).CommandArgument));
  }

And then you just set all the click events to that:

  btnFullBack.Click += btnPaging_Click;
  btnOneBack.Click += btnPaging_Click;
  btnOneForward.Click += btnPaging_Click;
  btnFullForward.Click += btnPaging_Click;

And boom, you’re pretty much set.

Dynamic Markup Property Collection for a WebControl

I wasn’t exactly sure how to write this title as it’s not easy to explain in a short sentence, however I can say that I am completely embarrassed by the result and may have to consider hiring a title consultant. However, for now it will have to do.

Ok so what is this about? Well let’s say you have the control from the last example and you don’t want a list of controls in the markup, but maybe you want a list of strings set in the markup. (Say for a list of settings) Or even better, let’s say you have controls already on the page but you want our ParentControl (Yes I said “our” but no I’m not proposing… yet) to do something with those controls. Say we want to have the ParentControl to assign some javascript to certain buttons on the page. Ok yeah, kind of dumb but that’s the example I made. I supposed you could think of it like this: You want a validation control to validate multiple controls but you want to give it the names of the controls in the markup. Anyways, let’s stick with the example I already have.

First off you’ll need to create a new class, something that you want to hold the information in. (Although truth be told I could do something way easier and just use a list of strings, but this should prove more interesting) Here’s the one I have:

  namespace Test.Frontend.ControlInControl
  {
    public class ChildControlDefinition
    {
        public String ControlName { get; set; }
    }
  }

Pretty sweet? Eh? Eh? No? Ok. So now we have a class, and that’s like wow. Now with the same attributes from the old example, build the WebControl:

    [ParseChildren(true)]
    [PersistChildren(false)]
    public partial class ParentControl : UserControl
    {
        public List<ChildControlDefinition> NamedControls { get; set; }
    }

Holy smokes, that just got way complicated compared to the last example. I added a whole new property NamedControls that is a list of the ChildControlDefinition class we created. Now you might notice that the AddedControls property from the old example isn’t there anymore. I just removed it to simplify this one.

And then there’s the markup:

    <asp:Button ID="mainButton" runat="server" />
    <uc1:ParentControl ID="ParentControl1" runat="server" >
        <NamedControls>
            <examples:ChildControlDefinition ControlName="mainButton" />
        </NamedControls>
    </uc1:ParentControl>

Now you might notice two things here:

1) There is a mark up section named “NamedControls” just like the collection. Can you guess why?

2) examples:ChildControlDefinition : This is the class type name and the TagPrefix for where the class is. For this to work, you have to register the assembly the class is in EVEN IF the class is in the web application assembly. So it would look like this:

<%@ Register Assembly="Test.Frontend" Namespace="Test.Frontend.ControlInControl" TagPrefix="examples" %>

Now what does this do for anyone? Possibly it prevents you from dying a little inside but it also allows you to find those controls within the usercontrol… Ah buh? Don’t worry, I’ll show you!

    [ParseChildren(true)]
    [PersistChildren(false)]
    public partial class ParentControl : UserControl
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            NamedControls.ForEach(ConnectButtonToClick);
        }

        private void ConnectButtonToClick(ChildControlDefinition control)
        {
            Button foundControl;

            foundControl = Page.FindControl(control.ControlName) as Button;

            if (foundControl != null)
            {
                foundControl.OnClientClick = "alert('clicked'); return false;";
            }
        }

        public List<ChildControlDefinition> NamedControls { get; set; }
    }

See what I did there? SOMETHING COMPLETELY USELESS and yes you too can now have that power. However, there might be something worth taking home from that example. From the list of ChildControlDefinition I was able to get the control name that I wanted to attach the worthless alert script to and attach it. How was that done? Well I just iterated through the ChildControlDefinition list, used the Page.FindControl method to find the control, and then set the OnClientClick method.

Now this example is pretty stupid but I hope you can see the overall value of this. One would be a paging controller that has a list of paging control names that it iterated through and sets various events so they can all work in harmony like one great big continuation of the Hands Across America utopia that just didn’t seem to make it.

Now to spin it Nintendo User Manual Style:

Think you are bad enough for Dynamic Controls? Take grab of the power within and dare to conquer! Take a chance, the world can be your for the taking! Dynamic is waiting…

Add Controls to Control in ASP.Net (With Less Pulp)

So this should be a fairly easy showing and you’ll be on your way quickly. Hell most likely you won’t finish this sentence before going somewhere else. BUT for those who brave this post, you will be rewarded… I hope.

So here’s the problem, you have a UserControl/WebControl/ExtenderControl/ScriptControl/… (Seriously?) that you want to be able to add controls to in the markup like thus:

<SomeControl>
  <ControlList>
    <asp:Label />
    <asp:Label />
  </ControlList>
</SomeControl>

As you see here, the idea is that SomeControl actually can dynamically house controls based on the markup. Seems like this should be hard, but in reality it’s pretty simple. First start with creating a user control, which I hope you know how to do. (I’m calling it ParentControl) Second open up the class file and let’s add some stuff.

    [ParseChildren(true)]
    [PersistChildren(false)]
    public partial class ParentControl : UserControl
    {
        public ParentControl()
        {
            addedControls = new List<WebControl>();
        }

        private List<WebControl> addedControls;

        public List<WebControl> AddedControls
        {
            get
            {
                return addedControls;
            }
        }
    }

And honestly, that’s the code needed but I’ll give a literary once over to make sure things are clear.

So first off you have to add a list of controls to the eh… control and create a property that is used to access it and this can actually be done verbosely:

        //Field
        private List<WebControl> addedControls;

        //Instantiation on constructor
        public ParentControl()
        {
            addedControls = new List<WebControl>();
        }

        //Property to access
        public List<WebControl> AddedControls
        {
            get
            {
                return addedControls;
            }
        }

OR the easy way (Which is not what the original example showed:

        public List<WebControl>AddedControls { get; set; }

As you can see, the 2.0 auto property syntax will actually work for this. So if you like that, you can save yourself some typing.

Ok so now we have a property, and field if you choose, to handle this. Sounds way too easy right? Well the magic is in the attributes:

    [ParseChildren(true)]
    [PersistChildren(false)]
    public partial class ParentControl : UserControl

And you’re all set. Now the markup:

    <userControl:ParentControl ID="ParentControl1" runat="server" >
        <AddedControls>
            <asp:Label ID="labelHi" runat="server" />
        </AddedControls>
    </userControl:ParentControl>

Still waiting for this to get complicated? Well you’re going to waiting for a long time because that’s it. When page load comes around will now have a list with the label in it. Pretty nice huh?

Make an Autocomplete Control a Webcontrol

[Part One] [Part Two] [Part Three] [Part Four] [Part Five]

So in the last post I showed the easy way to use the Toolkit Autocomplete control, but it might have left you with some questions like: Do I have to keep adding a textbox everytime I want an autocomplete control? Is there an easy way to make a composite control? Is this guy an idiot?

The easy answer is: yes.

Now I’m not a huge fan of making web project controls (.ascx) unless there is heavy style formatting. For the most part if its going to be usable somewhere else and it is fairly simple to represent codewise, I’ll put it in a class library as a WebControl or ScriptControl. So how is this done with the autocomplete?

For my examples, I’ll be using the same root namespace as the Script Control examples, namely Test.Examples.AutoCompleteExample. Now that I have a wonderful folder created I’m going to go ahead and create a WebControl Class named AutoCompleteControl.

Now when I create this new control there are some things I will need:
-Has to inherit from at least WebControl (ScriptControl example I will do later)
-Has to have a textbox (The autocomplete needs a target control)
-I would strongly suggest a certain amount of properties to be exposed, basically reflecting the properties on the autocomplete
-I added the implementing of ITextControl mainly to relfect a .Text property but that isn’t really needed. I just found this useful if you end up treating this control like a textbox for say validation purposes.

    public class AutoCompleteControl : WebControl, INamingContainer
    {
        private AutoCompleteExtender autoComplete;
        private TextBox textboxTarget;

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            autoComplete = new AutoCompleteExtender();
            autoComplete.ID = "autoCompleteMain";

            textboxTarget = new TextBox();
            textboxTarget.ID = "textboxTarget";

            Controls.Add(textboxTarget);
            Controls.Add(autoComplete);
        }

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

            autoComplete.TargetControlID = textboxTarget.ID;

            autoComplete.CompletionInterval = 5000;
            autoComplete.EnableCaching = EnableCaching;
            autoComplete.CompletionSetCount = CompletionSetCount;
            autoComplete.MinimumPrefixLength = MinimumPrefixLength;
            autoComplete.OnClientItemSelected = OnClientItemSelected;
            autoComplete.ServiceMethod = ServiceMethod;
            autoComplete.ServicePath = ServicePath;
        }

        public Int32 CompletionSetCount { get; set; }

        public Boolean EnableCaching { get; set; }

        public Int32 MinimumPrefixLength { get; set; }

        public String OnClientItemSelected { get; set; }

        public String ServiceMethod { get; set; }

        public String ServicePath { get; set; }

        public String Text
        {
            get
            {
                EnsureChildControls();
                return textboxTarget.Text;
            }
            set
            {
                EnsureChildControls();
                textboxTarget.Text = value;
            }
        }
    }

Well hell that was easy, wasn’t it? All I had to do is create the class, add the textbox and autocomplete as controls, and set a few properties. Voila, we now have a working autocomplete control. Now if you had read the last post on this (Page 3) then you might have noticed this new property:

CompletionInterval

What is that? Well apparently it deals with the amount of time a particular item is highlighted when hovering over it. Found this out the other day. SURPRISE!!

Couple of points from this:

Why?
– Well if nothing else, you now have a compostite control to use. The markup will supply the service location and the method to use, everything else is taken care of with this control.

– On top of that, this can now be snug in a class library (assembly) for reuse thus removing it’s need to be recopied everytime you need it in another web project.

– You can now inherit from this control to add fucntionality if you need.

– You can now convert this to a script control in order to access javascript events and other fun things.

So as you can see, this is a pretty good way to go.

Something else of note is the CreateChildControls/EnsureChildControls situation. CreateChildControls is a overridable method that is used to make sure that the controls themselves are created and handled. The nice thing about this is that you won’t run into the timing issues you might if you try to initialize controls in other methods like OnInit. Also, it allows you the use of the EnsureChildControls method. When this method is called, the CreateChildControls method is either called or not depending if it’s already been run. EnsureChildControls basically asks if CreateChildControls has been run. If it has then it doesn’t call it again, if it hasn’t then the method is called to create the controls. So as you can see, this makes it easy to guarantee that the controls have been created in order to access them. This becomes important with properties that are tied to controls as there is no guarantee that when a property is accessed the controls aren’t null. Kind of nice, huh?

Also you might have noticed that I set all the control properties that were “attached” to the autocomplete in prerender. Usually for safety, I don’t both setting any outward facing properties like that until prerender so that I know I have the latest and greatest values.

Just incase you needed the markup example:

<%@ Register Assembly="Test.Examples"
  Namespace="Test.Examples.AutoCompleteExample" TagPrefix="test" %>

<test:AutoCompleteControl ID="autoCompleteTest" runat="server"
  ServicePath="~/Service/AutocompleteWebControl.svc" ServiceMethod="GetUserNameList"
  CompletionSetCount="10" MinimumPrefixLength="1" />

HOLY SMOKES NO NEED FOR TEXTBOXES!!11

  using System.Web.UI;
  using System.Web.UI.WebControls;
  using AjaxControlToolkit;