Tuesday, March 24, 2009

Switching Between Grids in a Silverlight Control

 

I'm just getting started with Silverlight and I wanted to know how to switch between two different grids with different content.  In that way, the same Silverlight control can appear to serve different purposes as needed.

The trick is to define a container control that covers the entire surface, such as a Canvas or single cell grid.  Then add two or more container controls which hold the alternate content.  As long as only one of those container controls has the Visibility = Visible setting, that container will be the one rendered in the designer at compile time.  The rest of the ricontainers should have the Visiblity = Collapsed setting.

The following XAML code provides an example. The first grid is the outer container.  The second grid implements a grid of 9 buttons with the center button with a red background color.  The third grid implements a similar grid of 25 buttons.  The visibility of the grids can easily be managed in C# or VB code.

<UserControl x:Class="Silverlight.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<
Grid x:Name="LayoutRoot" Background="AliceBlue" Width="900" Height="250" ShowGridLines="True">
<
Grid.RowDefinitions>
<
RowDefinition></RowDefinition>
</
Grid.RowDefinitions>
<
Grid.ColumnDefinitions>
<
ColumnDefinition></ColumnDefinition>
</
Grid.ColumnDefinitions>

<
Grid x:Name="G09" Background="AliceBlue" Width="900" Height="250" ShowGridLines="True" Grid.Row="0" Grid.Column="0" Visibility="Visible">
<
Grid.RowDefinitions>
<
RowDefinition Height="84"></RowDefinition>
<
RowDefinition Height="83"></RowDefinition>
<
RowDefinition Height="83"></RowDefinition>
</
Grid.RowDefinitions>
<
Grid.ColumnDefinitions>
<
ColumnDefinition Width="300"></ColumnDefinition>
<
ColumnDefinition Width="300"></ColumnDefinition>
<
ColumnDefinition Width="300"></ColumnDefinition>
</
Grid.ColumnDefinitions>
<
Button Height="40" Width="50" Grid.Row="0" Grid.Column="0" x:Name="btnG09R0C0" Click="btnG09_Click" Content="R0C0" Tag="G09R0C0" VerticalAlignment="Bottom" HorizontalAlignment="Right"></Button>
<
Button Height="40" Width="50" Grid.Row="0" Grid.Column="1" x:Name="btnG09R0C1" Click="btnG09_Click" Content="R0C1" Tag="G09R0C1" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="0" Grid.Column="2" x:Name="btnG09R0C2" Click="btnG09_Click" Content="R0C2" Tag="G09R0C2" VerticalAlignment="Bottom" HorizontalAlignment="Left"></Button>
<
Button Height="40" Width="50" Grid.Row="1" Grid.Column="0" x:Name="btnG09R1C0" Click="btnG09_Click" Content="R1C0" Tag="G09R1C0" VerticalAlignment="Center" HorizontalAlignment="Right"></Button>
<
Button Height="40" Width="50" Grid.Row="1" Grid.Column="1" x:Name="btnG09R1C1" Click="btnG09_Click" Content="R1C1" Tag="G09R1C1" VerticalAlignment="Center" HorizontalAlignment="Center" Background="Red"></Button>
<
Button Height="40" Width="50" Grid.Row="1" Grid.Column="2" x:Name="btnG09R1C2" Click="btnG09_Click" Content="R1C2" Tag="G09R1C2" VerticalAlignment="Center" HorizontalAlignment="Left"></Button>
<
Button Height="40" Width="50" Grid.Row="2" Grid.Column="0" x:Name="btnG09R2C0" Click="btnG09_Click" Content="R2C0" Tag="G09R2C0" VerticalAlignment="Top" HorizontalAlignment="Right"></Button>
<
Button Height="40" Width="50" Grid.Row="2" Grid.Column="1" x:Name="btnG09R2C1" Click="btnG09_Click" Content="R2C1" Tag="G09R2C1" VerticalAlignment="Center" HorizontalAlignment="Center" ></Button>
<
Button Height="40" Width="50" Grid.Row="2" Grid.Column="2" x:Name="btnG09R2C2" Click="btnG09_Click" Content="R2C2" Tag="G09R2C2" VerticalAlignment="Top" HorizontalAlignment="Left"></Button>
</
Grid>
<
Grid x:Name="G25" Background="AliceBlue" Width="900" Height="250" ShowGridLines="True" Visibility="Collapsed" Grid.Row="0" Grid.Column="0" >
<
Grid.RowDefinitions>
<
RowDefinition Height="50"></RowDefinition>
<
RowDefinition Height="50"></RowDefinition>
<
RowDefinition Height="50"></RowDefinition>
<
RowDefinition Height="50"></RowDefinition>
<
RowDefinition Height="50"></RowDefinition>
</
Grid.RowDefinitions>
<
Grid.ColumnDefinitions>
<
ColumnDefinition Width="180"></ColumnDefinition>
<
ColumnDefinition Width="180"></ColumnDefinition>
<
ColumnDefinition Width="180"></ColumnDefinition>
<
ColumnDefinition Width="180"></ColumnDefinition>
<
ColumnDefinition Width="180"></ColumnDefinition>
</
Grid.ColumnDefinitions>
<
Button Height="40" Width="50" Grid.Row="0" Grid.Column="0" x:Name="btnG25R0C0" Click="btnG25_Click" Content="R0C0" Tag="G25R0C0" VerticalAlignment="Center" HorizontalAlignment="Right"></Button>
<
Button Height="40" Width="50" Grid.Row="0" Grid.Column="1" x:Name="btnG25R0C1" Click="btnG25_Click" Content="R0C1" Tag="G25R0C1" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="0" Grid.Column="2" x:Name="btnG25R0C2" Click="btnG25_Click" Content="R0C2" Tag="G25R0C2" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="0" Grid.Column="3" x:Name="btnG25R0C3" Click="btnG25_Click" Content="R0C3" Tag="G25R0C3" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="0" Grid.Column="4" x:Name="btnG25R0C4" Click="btnG25_Click" Content="R0C4" Tag="G25R0C4" VerticalAlignment="Center" HorizontalAlignment="Left"></Button>

<
Button Height="40" Width="50" Grid.Row="1" Grid.Column="0" x:Name="btnG25R1C0" Click="btnG25_Click" Content="R1C0" Tag="G25R1C0" VerticalAlignment="Center" HorizontalAlignment="Right"></Button>
<
Button Height="40" Width="50" Grid.Row="1" Grid.Column="1" x:Name="btnG25R1C1" Click="btnG25_Click" Content="R1C1" Tag="G25R1C1" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="1" Grid.Column="2" x:Name="btnG25R1C2" Click="btnG25_Click" Content="R1C2" Tag="G25R1C2" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="1" Grid.Column="3" x:Name="btnG25R1C3" Click="btnG25_Click" Content="R1C3" Tag="G25R1C3" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="1" Grid.Column="4" x:Name="btnG25R1C4" Click="btnG25_Click" Content="R1C4" Tag="G25R1C4" VerticalAlignment="Center" HorizontalAlignment="Left"></Button>

<
Button Height="40" Width="50" Grid.Row="2" Grid.Column="0" x:Name="btnG25R2C0" Click="btnG25_Click" Content="R2C0" Tag="G25R2C0" VerticalAlignment="Center" HorizontalAlignment="Right"></Button>
<
Button Height="40" Width="50" Grid.Row="2" Grid.Column="1" x:Name="btnG25R2C1" Click="btnG25_Click" Content="R2C1" Tag="G25R2C1" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="2" Grid.Column="2" x:Name="btnG25R2C2" Click="btnG25_Click" Content="R2C2" Tag="G25R2C2" VerticalAlignment="Center" HorizontalAlignment="Center" Background="Red"></Button>
<
Button Height="40" Width="50" Grid.Row="2" Grid.Column="3" x:Name="btnG25R2C3" Click="btnG25_Click" Content="R2C3" Tag="G25R2C3" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="2" Grid.Column="4" x:Name="btnG25R2C4" Click="btnG25_Click" Content="R2C4" Tag="G25R2C4" VerticalAlignment="Center" HorizontalAlignment="Left"></Button>

<
Button Height="40" Width="50" Grid.Row="3" Grid.Column="0" x:Name="btnG25R3C0" Click="btnG25_Click" Content="R3C0" Tag="G25R3C0" VerticalAlignment="Center" HorizontalAlignment="Right"></Button>
<
Button Height="40" Width="50" Grid.Row="3" Grid.Column="1" x:Name="btnG25R3C1" Click="btnG25_Click" Content="R3C1" Tag="G25R3C1" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="3" Grid.Column="2" x:Name="btnG25R3C2" Click="btnG25_Click" Content="R3C2" Tag="G25R3C2" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="3" Grid.Column="3" x:Name="btnG25R3C3" Click="btnG25_Click" Content="R3C3" Tag="G25R3C3" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="3" Grid.Column="4" x:Name="btnG25R3C4" Click="btnG25_Click" Content="R3C4" Tag="G25R3C4" VerticalAlignment="Center" HorizontalAlignment="Left"></Button>

<
Button Height="40" Width="50" Grid.Row="4" Grid.Column="0" x:Name="btnG25R4C0" Click="btnG25_Click" Content="R4C0" Tag="G25R4C0" VerticalAlignment="Center" HorizontalAlignment="Right"></Button>
<
Button Height="40" Width="50" Grid.Row="4" Grid.Column="1" x:Name="btnG25R4C1" Click="btnG25_Click" Content="R4C1" Tag="G25R4C1" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="4" Grid.Column="2" x:Name="btnG25R4C2" Click="btnG25_Click" Content="R4C2" Tag="G25R4C2" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="4" Grid.Column="3" x:Name="btnG25R4C3" Click="btnG25_Click" Content="R4C3" Tag="G25R4C3" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<
Button Height="40" Width="50" Grid.Row="4" Grid.Column="4" x:Name="btnG25R4C4" Click="btnG25_Click" Content="R4C4" Tag="G25R4C4" VerticalAlignment="Center" HorizontalAlignment="Left"></Button>
</
Grid>
</
Grid>
</
UserControl>



 



Hope that helps.



Joe Kunk

Microsoft MVP VB


Okemos, MI USA




Saturday, March 21, 2009

Silverlight does not support the GetNames() and GetValues() methods of the Enum class

 

In writing a Silverlight 3 beta 1 application, I wanted to define a series of Enums and have a method that would return a complete list of the enumeration values, both the text and the numeric value, for use in binding and/or database fields.  I have written similar routines in Winforms without issue.

I was disappointed to find that the Silverlight SDK supports only the Equals, GetName, GetUnderlyingType, IsDefined, Parse, ReferenceEquals, and ToObject methods.

You will notice the absence of the GetNames() and GetValues() methods that would simplify creating my desired list.

I was aware that the Silverlight runtime is a subset of the full .Net framework, but this is the first, but probably not the last, time that it bit me.

To get around this limitation, I had to add a bit more code in my enums.vb file.  I had to explicitly create a structure to hold the enum's name and value, then create an additional routine for each enum that returns a List of that structure.

The following code shows the final result for one enum, Visibility.  Each additional enum would require another Region similar to the Visibility region.

If anyone has a suggestion for more efficient code considering the limitations, I would be very happy to hear it.  Just leave a comment with your suggestion.

Hope that helps!

Joe Kunk
Microsoft MVP VB
Okemos, MI USA

 

Public Class enums
Public Structure EnumValue
Dim Name As String
Dim
Value As Integer
Public Sub New(ByVal _Name As String, ByVal _Value As Integer)
Name = _Name
Value = _Value
End Sub
End Structure

#Region
"Visibility"
Public Enum Visibility As Integer
'Remember to change the associated List function too
NotSet = 0
Collapsed = 2
Visible = 4
End Enum

Public Shared Function
VisibilityList(ByVal LanguageName As Language) _
As List(Of EnumValue)
'Required because Silverlight runtime does not have the GetNames()
Dim Result As New List(Of EnumValue)
Result.Add(New EnumValue("NotSet", 0))
Result.Add(New EnumValue("Collapsed", 2))
Result.Add(New EnumValue("Visible", 4))
Return Result
End Function
#End Region
End Class


 



Wednesday, March 18, 2009

GLUGnet Meeting Thursday March 18 2009 at Michigan State University

 

Following is information about GLUGnet’s March meeting:

Date: Thursday, Mar 19

Time: 6pm – 8pm

Location: 1260 Anthony Hall, MSU

Topic: An Introduction to Castle ActiveRecord, or How to Stop Writing CRUD

Nobody likes writing CRUD. After writing an obscene number of methods and stored procedures you are left with a mountain of repetitive, error-prone, data access code. Wouldn't it be great if you could spend that time writing actual business logic instead of being a plumber and writing the same old data access code? In this talk Michael Eaton will introduce you to an open-source framework called Castle ActiveRecord that will help you write less data access code and be more productive.

Speaker:

Michael Eaton is an independent consultant who lives in southern Michigan. Since 1994, Mike has been designing and implementing high quality, robust solutions using Microsoft technologies including .NET and SQL Server. When not working on projects or spending time with his family, he enjoys blogging, playing World of Warcraft and hanging out with friends.

www.glugnet.org

Sponsors for this month’s meeting:

· telerik

· Redgate

· liquidweb

· Devexpress

Upcoming Local Tech Events

Give Camp Lansing: April 24 – 26 (http://www.lansinggivecamp.org/)

A GiveCamp is a weekend-long event where software developers, designers, and database administrators donate their time to create custom software for non-profit organizations. It is being held at Impression 5 Science Center. You can participate as a volunteer or submit an application for a charity. For details contact info@lansinggivecamp.org

IgniteLansing: Date TDB. Tickets available Mar 20 (http://www.ignitelansing.com/)

Ignite is an event that is a social gathering to help spread knowledge and have fun.   The event is primarily about presentations, where people give very quick, 5 minute presentations about pretty much about any topic. The call for presentations is open if you would like to submit a topic.