[Silverlight] SaveFileDialog 会发生的小问题 - SecurityException: Dialogs must be user-initiated
这是一个很简单的范例…
可以把TextBox 里面的文字给写入到本端的档案…
但是会出现 "SecurityException: Dialogs must be user-initiated " ( 对话框必须要被使用者启动)
而且是偶尔会出现…
先介绍一下案例:
在txtContext中输入文字..然後按下 btnSave 可以存档…
XAML Code:
<UserControl x:Class="SaveFileDialogMemo.MainPage"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<TextBox Height="192" HorizontalAlignment="Left" Margin="12,20,0,0" Name="txtContext" VerticalAlignment="Top" Width="368" FontSize="14" AcceptsReturn="True" TextWrapping="Wrap" Text="如果等等的彈出視窗,你快速把他按掉有機會可以存檔成功" />
<Button Content="存檔" Height="32" HorizontalAlignment="Left" Margin="296,218,0,0" Name="btnSave" VerticalAlignment="Top" Width="84" FontSize="14" Click="btnSave_Click" />
</Grid>
</UserControl>
接下来我们来看看 btnSave 中的C# Code :
private void btnSave_Click(object sender, RoutedEventArgs e)
{
try{
SaveFileDialog sfd=new SaveFileDialog();
sfd.DefaultExt = ".txt";
sfd.Filter = "Text Files|*.txt|Log Files|*.log|All Files|*.*";
//把下一行注解掉一切就会正常
MessageBox.Show("稍微停一下按掉就会错,如果按得快一点就不会错!!");
if (sfd.ShowDialog() == true)
{
using (Stream stream = sfd.OpenFile())
{
using (StreamWriter writer = new StreamWriter(stream, System.Text.UnicodeEncoding.Unicode))
{
writer.Write(this.txtContext.Text);
writer.Close();
}
stream.Close();
}
}
}
catch(Exception ex)
{
MessageBox.Show(ex.StackTrace);
}
}
其中点击bntSave 的时候…
我会在 sfd.ShowDialog() 之前 叫出一个 MessageBox.Show("稍微停一下按掉就会错,如果按得快一点就不会错!!");
如果您稍微等一下…再按掉…Exception 就会出现了..如果你按得快一点就不会…
为了de这bug花了我一点时间..因为有时候会错有时候不会错….
查了msdn 提到一句话
The ShowDialog method can only be called from user-initiated code, such as a button Click event. If ShowDialog is called from code that is not user-initiated, such as a PageLoaded event, a SecurityException is thrown. In addition, there is a limit on the time allowed between when the user initiates the dialog and when the dialog is shown. If the time limit between these actions is exceeded, an exception will occur.
我简单翻译一下:
该 ShowDialog的只能被此用者给呼叫启动,像是一个按钮 Click 事件。 如果ShowDialog不是被使用者给呼叫的,如 PageLoaded 事件,会造成一个 SecurityException的 异常。此外,有一个允许的时间限制,当用户启动之间的对话,当对话框显示。 如果这行为之间的时间限制超标,就会发生异常。
很帅气吧…这种偶尔会对偶尔不对的bug超难找…
所以学到一个经验…当你要调用SaveFileDialog.ShowDialog() 时候,记得前面保持干净(应该是把
SaveFileDialog.ShowDialog()放在调用代码的最前面),不要有其他跟使用者的互动行为…有时间限制的…
范例源码:
https://skydrive.live.com/self.aspx/blogsource/SaveFileDialogMemo.rar?cid=19ad32092ea01e0d&sc=documents