有使用過Silverlight/WPF的朋友們不知道有沒有遇過一個問題:有時候想要跳出一個元件跟使用者互動,而且要鎖住原來的主畫面,等使用者操作完才能繼續操作主畫面,可是用MessageBox的話功能不夠,用ChildWindow的話功能又太多或是太複雜之類的問題…
有使用過Silverlight/WPF的朋友們不知道有沒有遇過一個問題:有時候想要跳出一個元件跟使用者互動,而且要鎖住原來的主畫面,等使用者操作完才能繼續操作主畫面,可是用MessageBox的話功能不夠,用ChildWindow的話功能又太多或是太複雜之類的問題…
難道就不能自訂一個元件,當它顯示的時候,會自動讓主畫面被鎖住,而且該元件的外觀和操作方式都可以自訂嗎?其實只要善用Grid容器,就可以簡單的做到這個功能喔!!
方法如下:
1. 首先我們打開一個標準的Silverlight+Web專案(WPF也可以喔),接著增加一個UserControl(範例中取名為MyModalControl)。
接著修改MyModalControl.xaml的內容,將控制項本身與LayoutRoot這個Grid的寬和高都設為Auto。
2. 修改LayoutRoot的背景色為#4C4969CC(透明度為30%)
3. 放置要和使用者互動的元件,為了精簡教學過程,怎麼做的這邊就不詳述,完成後如下圖。
4. 加入按鈕的Click事件,並加入移除這個控制項的程式碼,完成後的xaml與cs檔如下:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
mc:Ignorable="d"
x:Class="FakeModal.MyModalControl"
d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot" Background="#4C4969CC">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel.Effect>
<DropShadowEffect Opacity="0.5"/>
</StackPanel.Effect>
<i:Interaction.Behaviors>
<ei:MouseDragElementBehavior ConstrainToParentBounds="True"/>
</i:Interaction.Behaviors>
<Border BorderBrush="Black" BorderThickness="2,2,2,0" Height="32" Width="200" CornerRadius="10,10,0,0" Margin="10,0,0,0" HorizontalAlignment="Left" Background="White">
<TextBlock TextWrapping="Wrap" Text="FakeModal" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="18.667"/>
</Border>
<Border BorderBrush="Black" BorderThickness="2" Width="400" Height="150" CornerRadius="10" Background="White">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock TextWrapping="Wrap" Text="Is to make a fake modal that simple?" FontSize="18.667" Margin="0"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,30,0,0">
<Button x:Name="btnYes" Content="Yes" Width="80" Height="32" FontSize="16" Margin="10,0" Click="btnYes_Click"/>
<Button x:Name="btnNo" Content="No" Width="80" Height="32" FontSize="16" Margin="10,0" Click="btnNo_Click"/>
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
</Grid>
</UserControl>
using System.Windows.Controls;
namespace FakeModal
{
public partial class MyModalControl : UserControl
{
public MyModalControl()
{
InitializeComponent();
}
private void btnYes_Click(object sender, System.Windows.RoutedEventArgs e)
{
//you can do something here.
(this.Parent as Panel).Children.Remove(this);
}
private void btnNo_Click(object sender, System.Windows.RoutedEventArgs e)
{
//you can do something here.
(this.Parent as Panel).Children.Remove(this);
}
}
}
5. 到這邊就算是完成啦,再來就是讓它上場表演的時候了,在MainPage.xaml放一個Button叫它出來吧!!
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="FakeModal.MainPage"
Width="Auto" Height="Auto">
<Grid x:Name="LayoutRoot" Background="White">
<Button x:Name="btnShowModal" Content="Show Fake Modal" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="18.667" Click="btnShowModal_Click"/>
</Grid>
</UserControl>
using System.Windows.Controls;
namespace FakeModal
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void btnShowModal_Click(object sender, System.Windows.RoutedEventArgs e)
{
this.LayoutRoot.Children.Add( new MyModalControl());
}
}
}
6. 執行結果如下:
專案下載: