[Silverlight] SaveFileDialog 會發生的小問題 - SecurityException: Dialogs must be user-initiated

2010/10/13

這是一個很簡單的範例…
可以把TextBox 裡面的文字給寫入到本端的檔案…

但是會出現 "SecurityException: Dialogs must be user-initiated " ( 對話框必須要被使用者啟動)
而且是偶爾會出現…

先介紹一下案例:

sshot-8

在txtContext中輸入文字..然後按下 btnSave 可以存檔…


XMAL 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() 時候 記得前面保持乾淨不要有跟使用者的互動行為…有時間限制的…

範例:
讚一下:

下載:


0 意見:

程式 . 生活 . D小調.@2010 | Binary Design: One Winged Angel.