使用观察者模式在 Silverlight 中切换用户控件
有一篇技巧,见
http://tech.sina.com.cn/s/2008-07-03/1528718607.shtml
或
http://kb.cnblogs.com/page/42897/?page=1
讨论的是运用InitParams在Silverlight 2应用程序中切换用户控件,这是个很笨但是直观的解决方式。
但如果在控件中传值,那将怎么办?以上方法将毫无用途!
今天在一个老外的博客看到有个很巧妙的方法,不敢独享,现分享出来:
首先写个接口:
namespace PageSwitchSimple
{
public interface ISwitchable
{
void UtilizeState( object state );
}
}
然后写个切换类:
using System.Windows.Controls;
namespace PageSwitchSimple
{
public static class Switcher
{
public static PageSwitcher pageSwitcher;
public static void Switch( UserControl newPage )
{
pageSwitcher.Navigate( newPage );
}
public static void Switch( UserControl newPage, object state )
{
pageSwitcher.Navigate( newPage, state );
}
}
}
PageSwitcher 成员类:
前台代码:
<UserControl x:Class="PageSwitchSimple.PageSwitcher"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800" Height="600">
</UserControl>
后台代码:
using System;
using System.Windows.Controls;
namespace PageSwitchSimple
{
public partial class PageSwitcher : UserControl
{
public PageSwitcher()
{
InitializeComponent();
}
public void Navigate( UserControl nextPage )
{
this.Content = nextPage;
}
public void Navigate( UserControl nextPage, object state )
{
this.Content = nextPage;
ISwitchable s = nextPage as ISwitchable;
//这里真是太巧妙了,用于传object 参数!
if ( s != null )
{
s.UtilizeState( state );
}
else
{
throw new ArgumentException( "nextPage is not ISwitchable! "
+ nextPage.Name.ToString() );
}
}
}
}
然后写两个实现接口ISwitchable的用户控件:
控件一:
<UserControl x:Class="PageSwitchSimple.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock Text="Your Name: " FontSize="18" />
<TextBox x:Name="Name" FontSize="18" Width="150" Height="35" VerticalAlignment="Top" Margin="5"/>
<Button x:Name="ChangePage" Content="Change" FontSize="18" Width="100" Height="50" />
</Grid>
</UserControl>
后台代码:
using System.Windows;
using System.Windows.Controls;
namespace PageSwitchSimple
{
public partial class Page : UserControl, ISwitchable
{
public Page()
{
InitializeComponent();
ChangePage.Click += new RoutedEventHandler( ChangePage_Click );
}
void ChangePage_Click( object sender, RoutedEventArgs e )
{
Switcher.Switch( new Page2(), Name.Text );
}
}
}
控件二:
<UserControl x:Class="PageSwitchSimple.Page2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="Bisque">
<TextBlock x:Name="Message" Text="Page2" FontSize="18" />
<Button x:Name="ChangePage" Content="Change" FontSize="18" Width="100" Height="50" />
</Grid>
</UserControl>
后台代码:
using System.Windows;
using System.Windows.Controls;
namespace PageSwitchSimple
{
public partial class Page2 : UserControl, ISwitchable
{
public Page2()
{
InitializeComponent();
ChangePage.Click += new RoutedEventHandler( ChangePage_Click );
}
public void UtilizeState( object state )
{
Message.Text = state.ToString();
}
void ChangePage_Click( object sender, RoutedEventArgs e )
{
Switcher.Switch( new Page() );
}
}
}
最后修改App.cs
private void Application_Startup( object sender, StartupEventArgs e )
{
PageSwitcher pageSwitcher = new PageSwitcher();
this.RootVisual = pageSwitcher;
Switcher.pageSwitcher = pageSwitcher;
Switcher.Switch( new Page() );
}
巧妙运用了观察者模式,佩服作者的思路。
目前维护的开源产品:https://gitee.com/475660