In this section, you will preview the main system interfaces
so as to have a general understanding of the system.
System Preview
Figure 8 shows the main interface of the system. On this
page, in addition to tell about the developing techniques and operational
environment, the system also gave a brief description of the overall function.
Finally, clicking the hyperlink at the bottom right corner of the page will start
up your browser and navigate you to the author's blog page.
Figure 8-- the main interface of the system
Figure 9 shows the run-time screenshots of the image
category management module. Through this page, you can browse, add, edit, and delete
picture category data, as well as query your interested ones by specifying the
picture category name in the Textbox control. This page represents the typical
programming module that is associated with the backend data access techniques.
Through this module, you can learn how to create data centric solutions under
the Silverlight programming environment.
Figure 9-- the CRUD implementation of image
category data
Figure 10 shows the run-time screenshot relating to upload
and download image files, which is one of the most used parts in typical online
image management systems. Note here, taking into account the system performance
requirements, we've used the Silverlight-specific memory management technology,
i.e. Isolated Storage, in the realization of this module.
Figure 10-- Upload and download snapshot
Image browser module is the most complex subsystem module, which
is also a necessary part of any online image system. With the traditional image
browsing techniques, through the use of multi-reference version of Silverlight
technology, two-dimensional graphics and animation technology can be a very
flexible way of browsing image data to display. Figure 11 gives the related
snapshot, where you can click the thumbnail in the navigator bar to jump to appreciate
your target image.
Figure 11-- Click the bottom thumbnail image to
view it in the full-screen mode (non clicking happens now)
Nearly with all the necessary information in our mind, in
the next section, we start to roll our sleeves to construct the application
module by module.
Create the Sample Solution
Start Visual Studio 2008, open the "File" menu,
and from the pop-up "New" sub-menu select "Project" option,
then the "New Project" dialog box will appear. In the dialog box,
select the template namely "Silverlight Application", enter the
application name "S2PhotoAlbum", and click "OK" button.
As soon as you close the above dialog box, another dialog
box "Add Silverlight Application" will appear before you. Here we
select "ASP.NET Web Site" as the host project type.
From the beginning of the next section, we are going to
create XAML pages and write the related background C# code.
Home and Welcome Page module
To simplify the problem and due to the time constraint, the
image management system does not add a user registration and login module.
Therefore, as soon as the system is activated, you can see the system's home
page and welcome page module and directly use all the functionalities provided
in the system. The home page and welcome page in the module are implemented
through two Silverlight user controls, i.e. MainPage.xaml and Welcome.xaml.
(1) XAML Markup Code Page Design
First, we will explorer the layout design of the main page--
MainPage.xaml. Figure 12 gives the related snapshot (in Microsoft Expression
Blend 3) for page MainPage.xaml.
Figure 12-- the design time snapshot of page MainPage.xaml
In this sample application, we simply use a few custom buttons
on the left side of the page as navigation toolbar. The header at the top just
shows a logo image, while the footer lies at the bottom line, and the most part
on the right corresponds to a large and empty Grid control, used as a container
control of the sub XAML pages (Silverlight controls).
Now, let's look at the related XAML markup code for page
MainPage.xaml.
Listing 4-- the main XAML markup code for page
MainPage.xaml
<!--Main Canvas-->
<Grid x:Name="_rootMain">
<StackPanel x:Name="LayoutRoot" Orientation="Vertical" HorizontalAlignment="Center">
<StackPanel x:Name="logoContainer" Height="100" Width="800"
Background="#FF423442" HorizontalAlignment="Center" >
<Image Source="images/logo.jpg"></Image>
</StackPanel>
<Grid x:Name="gridBody" Background="#FF574C5B" Height="450"
ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="165" />
<ColumnDefinition Width="2" />
<ColumnDefinition Width="615" />
</Grid.ColumnDefinitions>
<ListBox x:Name="listCatalog" Margin="2,2,2,2" Grid.Row="0"
Grid.Column="0" Background="#FF5C4141" Width="160"
HorizontalAlignment="Left" >
<Button Height="32" Width="130" x:Name="btnHome" Content="Home"
Style="{StaticResource NewButtonTemplate}" FontSize="10.667"
Background="#FFFFFFFF" Foreground="#FF06A500"/>
<Button Height="32" Width="130" x:Name="btnCata"
Content="Category Management"
Style="{StaticResource NewButtonTemplate}"
FontSize="10.667" Foreground="#FF06A500"/>
<Button Height="32" Width="130" x:Name="btnDownUp"
Content="Upload & Download"
Style="{StaticResource NewButtonTemplate}" FontSize="10.667"
Foreground="#FF06A500"/>
<Button Height="32" Width="130" x:Name="btnBrow_Select"
Content="Select Category"
Style="{StaticResource NewButtonTemplate}" FontSize="10.667"
Foreground="#FF06A500"/>
<Button Height="32" Width="130" x:Name="btnBrow"
Content="Image Browser"
Style="{StaticResource NewButtonTemplate}" FontSize="10.667"
Foreground="#FF06A500"/>
<ToggleButton
x:Name="FullScreenButton"
Content="FullScreen/Window Switch"
Background="#000000"
Margin="2,0,4,5"
FontSize="10.667"
HorizontalAlignment="Stretch"
Style="{StaticResource ToggleButtonStyle}"
Visibility="Visible" Foreground="#FF00CBFF" />
</ListBox>
<basics:GridSplitter Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="3"
BorderThickness="1" BorderBrush="Blue" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"></basics:GridSplitter>
<Grid x:Name="gridRight" Grid.Row="0" Grid.Column="2"
Background="#FF5C4141" Margin="2,2,2,2" >
</Grid>
</Grid>
<Canvas x:Name="footer" Height="50" Width="800" Background="#FF4C4C4C">
<TextBlock Width="246.5" Text="By Xianzhong (WeiFang China) "
FontSize="20" Foreground="#FF00FB75"
HorizontalAlignment="Center" Height="32"
Canvas.Top="18.909" Canvas.Left="288"/>
<HyperlinkButton Style="{StaticResource CustHyperlink}"
Content="HyperlinkButton" Height="51" TargetName="Contace me"
FontSize="20" Width="144" HorizontalAlignment="Right"
Foreground="#FF46FF00" Canvas.Left="648" VerticalAlignment="Top"
Margin="0,0,0,0" Canvas.Top="5"/>
</Canvas>
</StackPanel>
</Grid>
</UserControl>
As is seen, the page itself is a user control (UserControl),
at the top of which is a StackPanel control which contains an Image control. The
Listbox control at the left side contains several Button controls used as the
navigator bar. The footer part uses a Canvas control as the layout container.
Another thing to take notice of is that the above hyperlink
control, button controls, full-screen/window switch control are all defined in
the main application App.xaml within the Resources property. For more details
about the Resources property in Silverlight apps, again please refer to MSDN.
Next, we will discuss the relevant background related programming.
(2) Background Code Design
Due to space limitations, we still will not give detailed
explanation of all the code, but to focus on clarifying the whole process and
crucial skills in Silverlight programming (for the other modules in this article
are also the case).
In this section, we plan to explain the following three
questions:
·
Sub .xaml pages switching principle inside a parent container
control
·
Full-screen and window mode switching principle
·
Several .xaml pages switching principle
(a) Sub .Xaml Pages Switching Principle
When you are running the sample app you may notice that when
you click the button controls on the left side a corresponding sub .xaml control
will be loaded into the Grid control on the right side of the page and display
the related contents. How to achieve this target?
In fact, the sub .xaml controls switching principle here is
very simple. As is known, each page is a UserControl control in essence. So we
can search through the control levels to find out the Grid control named gridRight. First, we can empty subset of its original control
set, and then by invoking the Add() method we can fill
the subset of control gridRight with our favorite .xaml
control.
For example, the following code achieved the result to load
the upload/download XAML page into the parent control gridRight.
Listing 5-- clear original sub controls and replace
with new target .xaml control
void btnDownUp_Click(object sender, RoutedEventArgs e)
{
gridRight.Children.Clear();//clear original sub controls
//load current XAML control
gridRight.Children.Add(new S2PhotoAlbum.XAMLs.UploadDownload());
}
(b) Full-Screen and Window Mode Switching
Principle
Similar to other applications, in Silverlight applications, it
is commonly required to provide the functionality to switch between the full-screen
mode and window mode. In the Silverlight application, how to achieve it?
The principle here is still simple. We can resort to control
ToggleButton which is defined in the namespace
System.Windows.Controls.Primitives to meet our request.
As the parent control of controls CheckBox and RadioButton,
ToggleButton provide the functionality to switch between two-state and
three-state.
First of all, in the constructor of page MainPage, we create
the following code:
Listing 6-- initialization for full-screen and
window state switching related stuff
public Page()
{
InitializeComponent();
//(others omitted)
//specify the button Click event handler
FullScreenButton.Click += new RoutedEventHandler(OnToggleFullScreen);
//also setup the FullScreenChanged event handler
if (Application.Current != null)
{
Application.Current.Host.Content.FullScreenChanged += OnFullScreenChanged;
}
//(others omitted)
}
The following code corresponds to the above two event
handlers.
Listing 7
// switch between the full-screen and window mode
private void OnToggleFullScreen(object sender, RoutedEventArgs e)
{
Application.Current.Host.Content.IsFullScreen =
(bool)FullScreenButton.IsChecked;
}
// the FullScreenChanged event handler
private void OnFullScreenChanged(object sender, EventArgs e)
{
//if app quits full-screen mode, then cancel checking button ToggleButton
if (!Application.Current.Host.Content.IsFullScreen &&
FullScreenButton != null)
{
FullScreenButton.IsChecked = false;
}
}
Finally, let's pay special attention to the whole .xaml
pages switching technique.
(c) Several .Xaml Pages Switching Principle
Our target here is that the current screen is one XAML page,
and it should be replaced by another XAML page. How to achieve it?
When the user clicks on the "Image Browser"
button, page MainPage.xaml should be turned into another XAML page--PhotoViewer.xaml
which does not serves as a part of Page.xaml page like the a
case discussed above.
Since currently Silverlight did not provide a similar
mechanism to meet our request, we need to do it by ourselves referring to the
case a solution used above and further generalize it. What
we need to do is monitor the process of page switching. In this end, we
designed three relevant classes to complete the above task:
·
TransitionCompletedEventArgs: responsible for monitoring the
events of switching between the two old and new XAML controls.
·
TransitionBase: an abstract base class to take charge of XAML
controls transition, whose derivation classes, such as FadeTransition,
RotateTransition, WipeTransition and CompositeTransition) are able to finish
the actual task of the old and new XAML pages transition (or switch) through class
TransitionCompletedEventArgs.
·
NavigationHelper: a helper class, with the help of the above two classes,
further encapsulates (or simplifies) switching manipulation between XAML pages.
Due to limited space, we are only going to discuss the
realization of class NavigationHelper and detailed notes.
Listing 8-- source code for class NavigationHelper
public static class NavigationHelper
{
///variable root represents the root element of the XAML file
private static Grid root;
///assign value to variable root
///(here refer to the Grid control, which maybe varies in other cases)
static NavigationHelper()
{
root = Application.Current.RootVisual as Grid;
}
///using specified dynamic transition effect achieve the target of switching
///between the old and the new XAML controls
public static void Navigate(TransitionBase transition, UserControl newPage)
{
UserControl oldPage = root.Children[0] as UserControl;
root.Children.Insert(0, newPage);
transition.TransitionCompleted += transition_TransitionCompleted;
transition.PerformTranstition(newPage, oldPage);
}
///make direct replacement (this simple case of above)
public static void Navigate(UserControl newPage)
{
UserControl oldPage = root.Children[0] as UserControl;
root.Children.Add(newPage);
root.Children.Remove(oldPage);
}
///when the transition completes, the following event is triggered, where the old XAML is removed
private static void transition_TransitionCompleted(object sender, TransitionCompletedEventArgs e)
{
root.Children.Remove(e.OldPage);
}
Finally, we take a look at how to use the above-mentioned classes
to navigate the application pages.
Listing 9
void btnBrow_Click(object sender, RoutedEventArgs e)
{
TransitionBase transition = new CompositeTransition(
new FadeTransition(TimeSpan.FromSeconds(1)),
new RotateTransition());
NavigationHelper.Navigate(transition, new S2PhotoAlbum.XAMLs.PhotoViewer());
}
It is clear that the first line of code specifies the effect
of dynamic transition, and using the static method Navigate
of the helper class NavigationHelper to switch to the
current page PhotoViewer using the specified transition effect.
In the last section, let's say a few words about the welcome
page.
Welcome Page Design
As shown in Figure 8 given above, when the system successfully
starts up, what appears before you is a simple system development introduction
page. This page is named Welcome.xaml, which is loaded into page MainPage.xaml at
the very beginning of the app is launched.
This welcome page is really simple and no more explanations shall
be repeated.