Blend, VS, Events and C#

From now until the summer I'll be working on videos, tutorials, presentations and blogging, but I'll also be writing Programming Silverlight 2 with Tim Heuer. Rather than convincing you that I'm continually hawking my book, I'd rather use the process of writing it as an opportunity to provide good, free, and I hope interesting material for this blog. (Write to me if I get the balance wrong!).

As an example, I ran into a bit of C# in what I'm writing in the first chapter that I thought made for an interesting example of how a Silverlight 2 programmer can? must? juggle the three principle technologies of (a) Visual Studio and (b) Blend and (c) a programming language of choice (which I can't quite understand why that wouldn't be C# or VB but I do know lots of folks disagree, and that in itself will make an interesting blog entry!)

So this blog entry may be of interest only for those of you who enjoy a bit of C#.

The context

This is early in the book and I'm laying out 9 checkboxes, used to designate search criteria. The first checkbox is "Any". If that is clicked the others are invisible,

AnyCheckBox

If Any is unchecked, all the other criteria appear,

AnyUnchecked

 

The book then goes on to show a number of things, including how to create the refining characteristics panels and how to overlay them, etc. etc. but the part I want to focus on here is a tiny detail: how you set the visibility flag on the check boxes. 

Here is the code I used.

private void AnyPropertyCheckBox_Click(object sender, RoutedEventArgs e)
{
    bool? isVisible = !AnyPropertyCheckBox.IsChecked;
    foreach (UIElement uie in LayoutRoot.Children)
    {
        CheckBox cb = uie as CheckBox;
        if (cb != null)
        {
            if (cb.Tag != null
                && cb.Tag.ToString().ToUpper() == "SEARCHCRITERIA")
            {
                cb.Visibility = isVisible == true ? 
                   Visibility.Visible : Visibility.Collapsed;
            }   // end if tag match
        }       // end if check box
    }           // end for each element
}               // end method

 

I'll walk through the entire method in just a second, but the key c# construct here is the use of the ternary operator (?:)

cb.Visibility = isVisible == true ? 
    Visibility.Visible : Visibility.Collapsed;

This operator (?:) is called ternary as it is the only operator that takes three parts. Here is how you read it (inside out).  First you evaluate the truth part  (isVisible==true).  This could have been written as

!AnyPropertyCheckBox.IsChecked == true

or

AnyPropertyCheckBox != IsChecked

To simplify I used an interim nullable boolean variable.

In any case, if the truth part evaluates true, then whatever is on the left side of the colon (in this case Visibility.Visible) is assigned as the result of the expression, otherwise, whatever is on the right side is assigned.

I admit, it is a construct only a former C programmer can love.

Note that the code I used  is exactly the same as writing

private void AnyPropertyCheckBox_Click(object sender, RoutedEventArgs e)
{
    bool? isVisible = !AnyPropertyCheckBox.IsChecked;
    foreach (UIElement uie in LayoutRoot.Children)
    {
        CheckBox cb = uie as CheckBox;
        if (cb != null)
        {
            if (cb.Tag != null
                && cb.Tag.ToString().ToUpper() == "SEARCHCRITERIA")
            {
               if ( isVisible == true )
               {
                   cb.Visibility = Visibility.Visible;
                }
                else
                {
                   cb.Visibility =  Visibility.Collapsed;
                }
            }   // end if tag match
        }       // end if check box
    }           // end for each element
}               // end method

 

So, as promised, here is the line by line walk through

// Declare isVisible to be a nullable boolean variable
// (it can have three values: true, false or null
// If AnyPropertyCheckBox's property IsChecked is true, assign false
// otherwise assign true.  This is dangerous code as the property could
// be null, and in retrospect I'd rewrite this as
// bool? isVisible = ! (AnyPropertyCheckBox.IsChecked == true);
// which would assign false if the property is true or null
bool? isVisible = !AnyPropertyCheckBox.IsChecked;

Next we iterate through all the children of LayoutRoot which is a grid that contains all the UIElements on the page

foreach (UIElement uie in LayoutRoot.Children)
{
     // code to explain here
}

Within that loop we'll grab each element and cast it to type Checkbox. The cast will either work or return null. If it does not return null, we'll ask the temporary check box if its tag is null. If not, then we have a check box with a tag and we can see if that tag, when turned to a string matches the tag we're looking for

// try casting to a checkBox
CheckBox cb = uie as CheckBox;

// if the cast is not null, it really was a check box
if (cb != null)
{
    // see if the tag is null and if not if the tag as a string
    // matches what we're looking for
    if (cb.Tag != null
        && cb.Tag.ToString().ToUpper() == "SEARCHCRITERIA")
    {
        // code here
    }   
}       

Note that the test for the tag not being null and then turning the tag into a string is accomplished in a single if statement. That is safe if you get the order right and use the && symbol between the two expressions, because they will short circuit. That is, because both must be true, if the first is false, the second will never evaluate (which is a good thing, because if the first is false, then the Tag is null and trying to call ToString on it would throw an exception).

Finally, inside the if statement is the ternary operator where we set the visibility.

Not bad, but not obvious if you're not comfortable with a bit of C#.

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in z Silverlight Archives. Bookmark the permalink.