Thursday, May 19, 2011

Create a Paging Button for each slide in an ASP.NET AjaxControlToolkit SlideShowExtender

I had been searching for days for a way to have pretty little buttons for each slide in my slideshow extender.
Here is the always sexy nivo slider. Notice that you can have a bullet for each slide. Also, it would be cool if you could extend this guy to show tiles of the slides instead of just bullets.

 Here is what every other tutorial for the SlideShowExtender for the ASP.NET AjaxControlToolkit produced:
eeek! Try and sell that shit to a customer and see what happens.

So why not just use JQuery you might ask?

1. I don't believe in rewriting code that is already well designed. That is like wiping my ass with hard earned $100 bills.

2. The SlideShowExtender has some really cool functionality that I haven't found in the JQuery controls.

Regardless, here is how to extend the control to use paging buttons that you can easily customize to look as you please with CSS. I didn't do any pretty stuff here-- just the secret to making it work.

I am assuming that you already have your slideshow extender on the page and working as all the other 5000 tutorials on the subject show you how to do. Here is the key addition:


<div style="text-aligncenter; ">
          <div class="SlideShowMainTitle">
            <asp:Label ID="lblSlideTitle" runat="server"></asp:Label>
          </div>
          <div class="SlideShowImage">
            <asp:Image ID="imgSlide" runat="server" />
          </div>
          <div class="SlideShowSubTitle">            
                <asp:Label ID="lblSlideDescription" runat="server"></asp:Label>     <br />
                <asp:Repeater ID="rpPagingButtons" runat="server" OnItemDataBound="rpPagingButtons_OnItemDataBound">
                    <ItemTemplate>
                        <a ID="lbtnPager" runat="server"></a> 
                    </ItemTemplate>
                </asp:Repeater>   
          </div>
          
            <asp:SlideShowExtender ID="slExtender" runat="server" AutoPlay="true" Loop="true" PlayInterval="3000" TargetControlID="imgSlide"
                 ImageTitleLabelID="lblSlideTitle" ImageDescriptionLabelID="lblSlideDescription" SlideShowServiceMethod="GetSlides" SlideShowServicePath="~/WebServices/SlideShowService.asmx">
            </asp:SlideShowExtender>
          
        </div>        

Then in the code behind:

        protected void rpPagingButtons_OnItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemIndex > -1)
            {
                HtmlAnchor lbtnPageLink = (HtmlAnchor)e.Item.FindControl("lbtnPager");
 
                if (lbtnPageLink != null)
                {
                    string behaviorID = slExtender.BehaviorID;
 
                    lbtnPageLink.HRef = "javascript:$find('" + behaviorID + "')._currentIndex= " + e.Item.ItemIndex.ToString() + ";" +
                                                 " $find('" + behaviorID + "').setCurrentImage();";
                   
                    lbtnPageLink.InnerHtml = (e.Item.ItemIndex + 1).ToString();
                }
            }
        }
The key is in the href for the anchor tag. You will need to bind some data to your repeater. The dataset needs to have a row for each image in your slide show. I am assuming that you already are a decent programmer and know how to customize this to your own needs. Basically, set your bullet image in the css for the anchor tag in your repeater. You can do all of your formatting there.


Now go make daddy some bloody money.

Thursday, May 5, 2011

Clearing Up Some Space on Your Main Partition: Coping with a love for the Intel SSD, but a programmer's budget)

I recently built the best machine that I could buy parts for. This thing had everything: the ASUS P6T6 rev with an Intel I7 extreme, the NVidia three-way-sli (well, you get the picture). However, when it came down to the hard drive decision, a co-worker of mine convinced me that I just had to buy the new Intel SSD-- so I did. The problem? While Windows 7 booted in under 6 seconds--and Fedora in under 3--, I had already spent most of my budget on the "important" stuff. Thus, I bought an 80GB drive for Windows, a 40GB drive for Linux, and an eSATA 1TB external drive for all of my "non-essential" data: which is cheaper than buying a single 160GB Intel SSD. I don't know if you have priced the Intel SSDs lately, but they are EXPENSIVE! So, I think to myself, "This should be fine, I'll just store all of my music, movies, and such on the external drive." This would have been fine if the data that took up the most space was music, movies, and such. Then reality hit.

Visual Studio and all of its dependencies > 7 GB
Microsoft office and all of its dependencies >  2GB
and so on.

As a developer, I have all of these tools that I have acquired over the years, and they add up quickly.

I failed to mention that I have one other secret love. I like to, on occasion, waste my time on really fun and cool video games--I mean, we can't let that three-way-sli go to waste can we? Here is the biggest problem:

Call of Duty Black Ops (looks amazing on this machine compared to X-Box 360 b.t.w) > 12GB
Empire Total War > 16 GB

This left me with no space. Dang it! So what do you do, when you have enough friends to party like its 1999, but nowhere to put them? You store them somewhere else, and project them to where you are as holograms--except for the women, they should actually be there. Anyhow, back to the point. Since Microsoft has finally figured out that all of the *NIX s are amazing--all of them except MAC at least :)--, they have finally begun copying them. In Vista, Server 2008, and Windows 7, Microsoft finally gave Windows users an invaluable tool: The Symbolic Link. For those of you who are not familiar with UNIX derivatives, a symbolic link is a file or a directory that is stored in one place but is linked to another location. This file or directory can then be accessed as if it physically resided at the target of the link. Why is this so helpful? Well, since many software programs on Windows will not allow you to install to a location outside of the partition that the OS resides on, you previously had no choice but to install to your precious SSD space. But now .....

Move the files that are space hogs over to a folder on your external hard drive-- say F:\ProgramFiles\Steam. Then run the following as an administrator from the command line:

mklink /D "C:\Program Files (x86)\Steam" F:\ProgramFiles\Steam

Voila! The OS won't know the difference, and you get your space back for the things you get paid for. Let's just call this the tasks where it actually matters how fast the data can be accessed. By the way, I can't tell the difference in speed when I run these programs from a symbolic link.

Saturday, April 16, 2011

Mercurial Tutorial by Joel Spolsky

For those of you fed up with spending an hour helping one of your programmers with a botched subversion merge,-- because you told them that if they change the tree they need to "add", "delete", or "move", but they didn't and so now the time you could be spending watching old Southpark episodes while eating Chinese food is being taken up by someone complaining about how they hate having to use version control-- this post by Joel Spolsky on switching to mercurial would be a good read. I will be playing with this tonight and possibly begin the move next week sometime.

http://hginit.com/

Friday, April 15, 2011

Treating a Thread as a Service

For those of you who have had to design software with many different logical components, you may have found it difficult to manage these components. Will they be in different applications, services, or daemons? Will they be in different threads or processes? The former may be a nightmare to maintain and the latter can be a nightmare to keep organized and bug free. I am going to propose a solution that is multi-threaded and well organized. So, here we go.

If you have ever tried to write a multi-threaded application, you may have found that object-oriented is a difficult goal to achieve. This is largely because you usually have to use static methods and such to spawn your threads. I wasn't too surprised when I discovered this with C/C++ and pthreads on Unix systems, but I was absolutely shocked when I tried to do this in C# using the System.Threading namespace. However, inspiration struck when I was working on an application using the ptlib library in Linux. They have this wonderful class called PThread which you can inherit from: overriding the virtual Main method and allowing you to treat each thread like an individual program in memory making it much easier to organize as a component in your overall architecture. So I thought, hmmm...., there has to be something like this in the .NET environment, but as I searched, I found nothing. So, I decided why not write one?




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace LionFront
{
///
/// This class is an attempt to handle a thread in a completely object oriented manner.
/// The attempt is to make this class similar in concept and funtion to the PTLib PThread class.
/// To use this class, create a class which inherits from this class. Override the Main() method to
/// call the code you want invoked. This will allow you to create mini-programs from within your main thread
/// and to treat them that way
///

public abstract class ThreadClass
{
private Thread thread;
private static int count;
        protected bool continue = false;
 /// 
/// Constructor. Initializes a thread to use your class.
///

///
/// The priority for the OS to place on this thread.
///
///
/// Whether or not to start the thread upon construction.
///
///
/// Then name of the class using this one. This will be part of the thread name attribute.
///
public ThreadClass(ThreadPriority priority, bool start, string className)
{
thread = new Thread(new ThreadStart(Main));
thread.Priority = priority;

count++;
thread.Name = className + count.ToString();

if (start)
thread.Start();
}
/// Override this method to call the code from your class.
/// This will be invoked by the thread upon startup.
///
protected abstract void Main();

public ThreadState State
{
get { return thread.ThreadState; }
}

public string Name
{
get { return thread.Name; }
}

public int ThreadID
{
get { return thread.ManagedThreadId; }
}

public virtual void Start()
{
            continue = true;
thread.Start();
}

public virtual void Pause()
{
thread.Suspend();
}

public virtual void Resume()
{
thread.Resume();
}

public virtual void End()
{
            continue = false
thread.Abort();
}
}
}


Voila! You have a reusable Threading Class. This is a very simple class. First, we encapsulate a System.Threading.Thread:

private Thread thread;


Next, we have an abstract (the same as virtual void method() = 0; in your c++ header) method that all subclasses must implement.

protected abstract void Main();        


Finally, in the constructor, we just tell our thread to use the Main method.

thread = new Thread(new ThreadStart(Main));
Now, how do we use this?

Here is a sample. The following class listens to a socket for input from a remote server and processes the information. If it receives the signal, it will fire the event back to the main program via a delegate.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LionFront
{
public enum DigitalInput : ushort
{
input1 = 0,
input2,
input3
}
public delegate void DigitalInputCallback(string ipAddress, DigitalInput input);

public class DigitalIO : ThreadClass
{
private static DigitalInputCallback inputCallback;
private static DigitalIO instance;
private static bool initialized;
private static List ipAddressList;

public DigitalIO(DigitalInputCallback callback)
: base(System.Threading.ThreadPriority.Highest, false, "DigitalIO")
{
inputCallback = callback;

if (!initialized)
{
ipAddressList = new List();
initialized = true;
instance = this;
instance.Start();
}
}

~DigitalIO()
{
this.End();

ipAddressList.Clear();

}

protected override void Main()
{
SendReceivePackets inputSignal = new SendReceivePackets(SendReceivePackets.GetIPAddress(), 35100);
inputSignal.BeginListen();

byte[] data = new byte[1000];

while (inputSignal.ReceiveData(ref data))
{
if (continue)
{
int startPos = 0;
int endValue = SendReceivePackets.ParseStream(startPos, data) - startPos;
string ipAddress = Encoding.UTF8.GetString(data, startPos, endValue);

startPos = endValue + startPos + 1;
endValue = SendReceivePackets.ParseStream(startPos, data) - startPos;

ushort input = Convert.ToUInt16(Encoding.UTF8.GetString(data, startPos, endValue));

inputCallback(ipAddress, (DigitalInput)input);
}
}
}
}


Here, we just wrote a normal class (in this case, our own signaling protocol), except for we give it its own Main loop by overriding the Main method. This allows us to write virtually any component that we need to run on its own thread. All we had to do was override the Main Method. Then, to use this component, you would just initialize this class in your application at whatever scope you want it to run on. However, make sure you end the thread when it goes out of scope or it will keep going; thankfully, C# still has destructors. This allows you to have as many different services running inside your application as you would like, and each will run on its own thread.

That is all for now. Happy Coding!