Silverlight 调用模态子窗口
Silverlight 3 新增了ChildWindow类,用于模拟模态显示窗口。但ChildWindow类的Show()方法却是非阻塞调用方法,必须配合ChildWindow类的Closed事件,才能完成模态窗口的调用。
子窗口如图,Xaml代码如下:
<basics:ChildWindow
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="SilverlightApplication1.SetColRowDlg"
Title="ChildWindow1"
Width="auto" Height="auto" mc:Ignorable="d" >
<Grid Background="White" Margin="10,5">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Margin="5,3" VerticalAlignment="Center" Text="Rows:" />
<TextBlock Margin="5,3" Text="Cols:" Grid.Row="1" VerticalAlignment="Center"/>
<TextBox Name="rowCount" Margin="5,3" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" />
<TextBox Name="colCount" Margin="5,3" Grid.Column="1" VerticalAlignment="Center" />
</Grid>
<Grid Margin="10,10,10,0" Grid.RowSpan="2" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="OKButton" Content="确定" Click="OKButton_Click" Grid.Column="1" Margin="5,3" Padding="20,3"/>
<Button x:Name="CancelButton" Content="取消" Click="CancelButton_Click" Margin="5,3" Padding="20,3" />
</Grid>
</Grid>
</basics:ChildWindow>
ChildWindow1.Xaml.cs 代码:
public partial class SetColRowDlg : ChildWindow
{
public SetColRowDlg()
{
InitializeComponent();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
}
在主窗口中,要用两个方法,一个用于显示子窗口,一个用于处理子窗口关闭事件。代码如下:
public partial class MainPage : UserControl
{
public MainPage()
{
// 为初始化变量所必需
InitializeComponent();
}
private ChildWindow1 cw; // 定义子窗口引用
private int rowCount = 8;
private int colCount = 8;
//处理子窗口关闭事件
private void ChildWindowClosed(object sender, EventArgs e)
{if(cw.DialogResult == true)
{
this.colCount = int.Parse(cw.colCount.Text);
this.rowcount = int.Parse(cw.rowCount.Text);//…
}
}//用于显示子窗口
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{cw = new ChildWindow1();
cw.Closed += ChildWindowClosed;
cw.colCount.Text = colCount.ToString();
cw.rowCount.Text = rowCount.ToString();
cw.Show();}
}
尽管上面的程序可以完成模态显示的任务,但是主窗口严重依赖于子窗口的实现细节,也违背了面向对象的精神。那么,有没有好的方法实现呢?
其实,可以将向子窗口传递的数据和子窗口向主窗口返回的数据封装在子窗口类中,再向子窗口传递一个委托,以便子窗口在关闭时调用主窗口的回调方法,代码如下:
public partial class MainPage : UserControl
{
public MainPage()
{
// 为初始化变量所必需
InitializeComponent();
}
private int rowCount = 8;
private int colCount = 8;
//主窗口回调方法
private void SetColRowCallback(int colCount, int rowCount)
{this.colCount = colCount;
this.rowcount = rowCount;//…
}
//用于显示子窗口
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{SetColRowDlg.Show(colCount, rowCount, SetColRowCallback);
}
}
子窗口代码如下:
public partial class SetColRowDlg : ChildWindow
{
public SetColRowDlg()
{
InitializeComponent();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
private Action<int,int> setColRowCallback;
public static void Show(int colCount, int rowCount, Action<int,int> setColRowCallback)
{
SetColRowDlg w = new SetColRowDlg();
w.colCount.Text = colCount.ToString();
w.rowCount.Text = rowCount.ToString();
w.setColRowCallback = setColRowCallback;
w.Show();
}
private void ChildWindow_Closed(object sender, EventArgs e)
{
if (DialogResult == true)
{
setColRowCallback(int.Parse(colCount.Text), int.Parse(rowCount.Text));
}
}
}
}

浙公网安备 33010602011771号