對話方塊概觀
獨立應用程式通常會有主視窗,這兩者都會顯示應用程式運作的主要資料,並公開功能,以透過使用者介面 (UI) 機制來處理該資料,例如功能表列、工具列和狀態列。 重要的應用程式還可能顯示其他視窗來執行下列動作:
對使用者顯示特定資訊。
向使用者收集資訊。
顯示並收集資訊。
這種視窗稱為「對話方塊」,可分為兩種類型︰強制回應和非強制回應。
當某個函式需要使用者提供其他資料才能繼續時,該函式會顯示「強制回應」對話方塊。 由於該函式需要透過強制回應對話方塊收集資料,因此當強制回應對話方塊保持開啟時,也可以防止使用者在應用程式中啟動其他視窗。 在大多數情況下,強制回應對話方塊可讓使用者藉由按下 [確定] 或 [取消] 按鈕,指出完成強制回應對話方塊。 按下 [確定] 按鈕表示使用者已輸入資料,並且希望此函式繼續處理該資料。 按下 [取消] 按鈕表示使用者想要完全停止執行此函式。 強制回應對話方塊的最常見範例為開啟、儲存及列印資料。
另一方面,「非強制回應」對話方塊在開啟時,不會防止使用者啟動其他視窗。 例如,如果使用者想要尋找出現在文件中的特定字組,主視窗通常會開啟對話方塊,詢問使用者要尋找哪個字組。 不過,由於尋找字組並不會防止使用者編輯文件,因此對話方塊不需要是強制回應。 非強制回應對話方塊至少會提供 [關閉] 按鈕以關閉對話方塊,並可能會提供其他按鈕以執行特定函式,例如 [尋找下一個] 按鈕以尋找下一個符合字組搜尋準則的字組。
Windows Presentation Foundation (WPF) 可讓您建立數種類型的對話方塊,包括訊息方塊、通用對話方塊和自訂對話方塊。 本主題將討論每種類型,而 Dialog Box Sample (對話方塊範例) 將提供相符的範例。
訊息方塊
「訊息方塊」是可用來顯示文字資訊,並讓使用者透過按鈕做出決定的對話方塊。 下圖所示的訊息方塊顯示文字資訊、提出問題,並提供使用者三個按鈕來回答問題。
若要建立訊息方塊,您可以使用 類別 MessageBox 。 MessageBox 可讓您使用如下所示的程式碼來設定訊息方塊文字、標題、圖示和按鈕。
// Configure the message box to be displayed
string messageBoxText = "Do you want to save changes?";
string caption = "Word Processor";
MessageBoxButton button = MessageBoxButton.YesNoCancel;
MessageBoxImage icon = MessageBoxImage.Warning;
' Configure the message box to be displayed
Dim messageBoxText As String = "Do you want to save changes?"
Dim caption As String = "Word Processor"
Dim button As MessageBoxButton = MessageBoxButton.YesNoCancel
Dim icon As MessageBoxImage = MessageBoxImage.Warning
若要顯示訊息方塊,您可以呼叫 static
Show 方法,如下列程式碼所示。
// Display message box
MessageBox.Show(messageBoxText, caption, button, icon);
' Display message box
MessageBox.Show(messageBoxText, caption, button, icon)
當顯示訊息方塊的程式碼必須偵測及處理使用者的決定時 (按下哪個按鈕),程式碼可以查看訊息方塊結果,如下列程式碼所示。
// Display message box
MessageBoxResult result = MessageBox.Show(messageBoxText, caption, button, icon);
// Process message box results
switch (result)
{
case MessageBoxResult.Yes:
// User pressed Yes button
// ...
break;
case MessageBoxResult.No:
// User pressed No button
// ...
break;
case MessageBoxResult.Cancel:
// User pressed Cancel button
// ...
break;
}
' Display message box
Dim result As MessageBoxResult = MessageBox.Show(messageBoxText, caption, button, icon)
' Process message box results
Select Case result
Case MessageBoxResult.Yes
' User pressed Yes button
' ...
Case MessageBoxResult.No
' User pressed No button
' ...
Case MessageBoxResult.Cancel
' User pressed Cancel button
' ...
End Select
如需使用訊息方塊的詳細資訊,請參閱 MessageBox 、 MessageBox 範例 和 對話方塊範例 。
雖然 MessageBox 可能會提供簡單的對話方塊使用者體驗,但使用 MessageBox 的優點是,這是在部分信任安全性沙箱內執行的應用程式唯一可以顯示的視窗類型(請參閱 安全性 ),例如 XAML 瀏覽器應用程式(XBAP)。
大多數對話方塊所顯示及收集的資料會比訊息方塊的結果更複雜,包括文字、選取範圍 (核取方塊)、互斥選取範圍 (選項按鈕),以及清單選取範圍 (清單方塊、下拉式方塊、下拉式清單方塊)。 針對這些情況,Windows Presentation Foundation (WPF) 提供數個常見的對話方塊,並可讓您建立自己的對話方塊,不過使用任一個都僅限於完全信任執行的應用程式。
一般對話方塊
Windows 會實作所有應用程式通用的各種可重複使用對話方塊,包括開啟檔案、儲存檔案和列印的對話方塊。 由於這些對話方塊是由作業系統實作,因此可在作業系統上執行的所有應用程式之間共用,以協助確保使用者體驗的一致性;當使用者在一個應用程式中熟悉如何使用某個作業系統提供的對話方塊時,就不需要了解如何在其他應用程式中使用該對話方塊。 因為這些對話方塊可供所有應用程式使用,並協助提供一致的使用者體驗,所以稱為「通用對話方塊」。
Windows Presentation Foundation (WPF) 封裝開啟的檔案、儲存檔案和列印通用對話方塊,並將它們公開為受控類別,讓您在獨立應用程式中使用。 本主題提供每個對話方塊的簡短概觀。
開啟 [檔案] 對話方塊
如下圖所示,檔案開啟功能使用 [開啟檔案] 對話方塊,來擷取要開啟之檔案的名稱。
通用開啟的檔案對話方塊會實作為 類別, OpenFileDialog 且位於 命名空間中 Microsoft.Win32 。 下列程式碼示範如何建立、設定及顯示一個對話方塊,以及如何處理結果。
// Configure open file dialog box
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".txt"; // Default file extension
dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension
// Show open file dialog box
Nullable<bool> result = dlg.ShowDialog();
// Process open file dialog box results
if (result == true)
{
// Open document
string filename = dlg.FileName;
}
' Configure open file dialog box
Dim dlg As New Microsoft.Win32.OpenFileDialog()
dlg.FileName = "Document" ' Default file name
dlg.DefaultExt = ".txt" ' Default file extension
dlg.Filter = "Text documents (.txt)|*.txt" ' Filter files by extension
' Show open file dialog box
Dim result? As Boolean = dlg.ShowDialog()
' Process open file dialog box results
If result = True Then
' Open document
Dim filename As String = dlg.FileName
End If
如需開啟檔案對話方塊的詳細資訊,請參閱 Microsoft.Win32.OpenFileDialog 。
注意
OpenFileDialog 可用於透過部分信任執行的應用程式安全地擷取檔案名(請參閱 安全性 )。
儲存對話方塊
如下圖所示,檔案儲存功能使用 [儲存檔案] 對話方塊,來擷取要儲存之檔案的名稱。
通用儲存檔案對話方塊會實作為 SaveFileDialog 類別,且位於 命名空間中 Microsoft.Win32 。 下列程式碼示範如何建立、設定及顯示一個對話方塊,以及如何處理結果。
// Configure save file dialog box
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".txt"; // Default file extension
dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension
// Show save file dialog box
Nullable<bool> result = dlg.ShowDialog();
// Process save file dialog box results
if (result == true)
{
// Save document
string filename = dlg.FileName;
}
' Configure save file dialog box
Dim dlg As New Microsoft.Win32.SaveFileDialog()
dlg.FileName = "Document" ' Default file name
dlg.DefaultExt = ".txt" ' Default file extension
dlg.Filter = "Text documents (.txt)|*.txt" ' Filter files by extension
' Show save file dialog box
Dim result? As Boolean = dlg.ShowDialog()
' Process save file dialog box results
If result = True Then
' Save document
Dim filename As String = dlg.FileName
End If
如需 [儲存檔案] 對話方塊的詳細資訊,請參閱 Microsoft.Win32.SaveFileDialog 。
列印對話方塊
如下圖所示,列印功能使用 [列印] 對話方塊,來選擇及設定使用者想要列印資料的目標印表機。
通用列印對話方塊會實作為 PrintDialog 類別,且位於 命名空間中 System.Windows.Controls 。 下列程式碼示範如何建立、設定及顯示一個對話方塊。
// Configure printer dialog box
System.Windows.Controls.PrintDialog dlg = new System.Windows.Controls.PrintDialog();
dlg.PageRangeSelection = PageRangeSelection.AllPages;
dlg.UserPageRangeEnabled = true;
// Show save file dialog box
Nullable<bool> result = dlg.ShowDialog();
// Process save file dialog box results
if (result == true)
{
// Print document
}
' Configure printer dialog box
Dim dlg As New PrintDialog()
dlg.PageRangeSelection = PageRangeSelection.AllPages
dlg.UserPageRangeEnabled = True
' Show save file dialog box
Dim result? As Boolean = dlg.ShowDialog()
' Process save file dialog box results
If result = True Then
' Print document
End If
如需列印對話方塊的詳細資訊,請參閱 System.Windows.Controls.PrintDialog 。 如需 WPF 中列印的詳細討論,請參閱 列印概觀 。
自訂對話方塊
雖然通用對話方塊很有用,而且應該盡可能使用,但這類對話方塊並不支援定義域專屬對話方塊的需求。 在此情況下,您必須建立自己的對話方塊。 如稍後所示,對話方塊是具有特殊行為的視窗。 Window 會實作這些行為,因此,您可以使用 Window 來建立自訂強制回應和無強制回應對話方塊。
建立強制回應自訂對話方塊
本主題示範如何使用 Window 對話方塊作為範例來建立一般強制回應對話方塊實 Margins
作(請參閱 對話方塊範例 )。 Margins
下圖顯示對話方塊。
設定強制回應對話方塊
一般對話方塊的使用者介面包括:
收集想要的資料所需的各種控制項。
使用者按一下以關閉對話方塊、返回函式,並繼續處理的 [確定 ] 按鈕。
使用者 按一下以關閉對話方塊並停止函式進一步處理的 [取消 ] 按鈕。
標題列中的 [關閉 ] 按鈕。
圖示。
最小化 、 最大化 和 還原 按鈕。
系統 功能表,可將對話方塊最小化、最大化、還原及關閉。
開啟對話方塊之視窗中央和上方的位置。
能夠盡可能調整大小,以防止對話方塊太小,並為使用者提供有用的預設大小。 這需要您同時設定預設值和最小維度。
ESC 鍵做為鍵盤快速鍵,導致 按下 [取消 ] 按鈕。 您可以將 [取消 ] 按鈕的 屬性設定 IsCancel 為
true
,以執行此動作。ENTER (或 RETURN) 鍵做為鍵盤快速鍵,導致 按下 [確定 ] 按鈕。 您可以藉由設定 IsDefault [確定 ] 按鈕
true
的 屬性來執行此動作。
下列程式碼示範這項設定。
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.MarginsDialogBox"
xmlns:local="clr-namespace:SDKSample"
Title="Margins"
Height="190"
Width="300"
MinHeight="10"
MinWidth="300"
ResizeMode="CanResizeWithGrip"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner"
FocusManager.FocusedElement="{Binding ElementName=leftMarginTextBox}">
<Grid>
<!-- Accept or Cancel -->
<StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="4">
<Button Name="okButton" Click="okButton_Click" IsDefault="True">OK</Button>
<Button Name="cancelButton" IsCancel="True">Cancel</Button>
</StackPanel>
</Grid >
</Window>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace SDKSample
{
public partial class MarginsDialogBox : Window
{
public MarginsDialogBox()
{
InitializeComponent();
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Input
Namespace SDKSample
Public Class MarginsDialogBox
Inherits Window
Public Sub New()
Me.InitializeComponent()
End Sub
End Class
End Namespace
對話方塊的使用者體驗也會延伸至開啟對話方塊之視窗的功能表列。 當功能表項目所執行的函式需要透過對話方塊進行使用者互動才能繼續時,該函式的功能表項目會在其標頭中顯示省略符號,如下所示。
<!--Main Window-->
<MenuItem Name="formatMarginsMenuItem" Header="_Margins..." Click="formatMarginsMenuItem_Click" />
當功能表項目所執行的函式顯示不需要使用者互動的對話方塊時 (例如 [關於] 對話方塊),則不需要省略符號。
開啟強制回應對話方塊
對話方塊通常是使用者選取功能表項目以執行定義域專屬函式所顯示的結果,例如在文書處理器中設定文件的邊界。 將視窗顯示為對話方塊類似於顯示標準視窗,不過需要進行額外的對話方塊專屬設定。 具現化、設定及開啟對話方塊的整個過程如下列程式碼所示。
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
namespace SDKSample
{
public partial class MainWindow : Window
{
bool needsToBeSaved;
void formatMarginsMenuItem_Click(object sender, RoutedEventArgs e)
{
// Instantiate the dialog box
MarginsDialogBox dlg = new MarginsDialogBox();
// Configure the dialog box
dlg.Owner = this;
dlg.DocumentMargin = this.documentTextBox.Margin;
// Open the dialog box modally
dlg.ShowDialog();
}
}
}
Imports System.ComponentModel
Imports System.Windows
Imports System.Windows.Controls
Imports Microsoft.Win32
Namespace SDKSample
Public Class MainWindow
Inherits Window
Private Sub formatMarginsMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Instantiate the dialog box
Dim dlg As New MarginsDialogBox
' Configure the dialog box
dlg.Owner = Me
dlg.DocumentMargin = Me.documentTextBox.Margin
' Open the dialog box modally
dlg.ShowDialog()
End Sub
End Class
End Namespace
在這裡,程式碼會將預設資訊(目前邊界)傳遞給對話方塊。 它也會使用顯示對話方塊之視窗的參考來設定 Window.Owner 屬性。 一般而言,您一律必須設定對話方塊的主控視窗,以提供所有對話方塊通用的視窗狀態相關行為 (如需詳細資訊,請參閱 WPF 視窗概觀)。
注意
您必須提供擁有者來支援對話方塊的使用者介面(UI) 自動化(請參閱 消費者介面自動化概觀 )。
設定對話方塊之後,呼叫 方法會以 ShowDialog 強制回應方式顯示對話方塊。
驗證使用者提供的資料
在開啟對話方塊且使用者提供所需資料之後,對話方塊會基於下列原因負責確保提供的資料有效:
從安全性的觀點來看,應該驗證所有輸入。
從定義域專屬的觀點來看,資料驗證可以防止程式碼處理錯誤的資料,這可能會擲回例外狀況。
從使用者體驗的觀點來看,對話方塊可藉由對使用者顯示哪些輸入的資料無效來協助使用者。
從效能的觀點來看,多層式應用程式中的資料驗證可以減少用戶層與應用程式層之間的來回行程次數,特別是當應用程式是由 Web 服務或伺服器架構資料庫組成時。
若要驗證 WPF 中的繫結控制項,您必須定義驗證規則,並將它與系結產生關聯。 驗證規則是衍生自 ValidationRule 的自訂類別。 下列範例示範驗證規則 , MarginValidationRule
它會檢查系結值是否為 Double ,且位於指定的範圍內。
using System.Globalization;
using System.Windows.Controls;
namespace SDKSample
{
public class MarginValidationRule : ValidationRule
{
double minMargin;
double maxMargin;
public double MinMargin
{
get { return this.minMargin; }
set { this.minMargin = value; }
}
public double MaxMargin
{
get { return this.maxMargin; }
set { this.maxMargin = value; }
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
double margin;
// Is a number?
if (!double.TryParse((string)value, out margin))
{
return new ValidationResult(false, "Not a number.");
}
// Is in range?
if ((margin < this.minMargin) || (margin > this.maxMargin))
{
string msg = string.Format("Margin must be between {0} and {1}.", this.minMargin, this.maxMargin);
return new ValidationResult(false, msg);
}
// Number is valid
return new ValidationResult(true, null);
}
}
}
Imports System.Globalization
Imports System.Windows.Controls
Namespace SDKSample
Public Class MarginValidationRule
Inherits ValidationRule
Private _maxMargin As Double
Private _minMargin As Double
Public Property MaxMargin() As Double
Get
Return Me._maxMargin
End Get
Set(ByVal value As Double)
Me._maxMargin = value
End Set
End Property
Public Property MinMargin() As Double
Get
Return Me._minMargin
End Get
Set(ByVal value As Double)
Me._minMargin = value
End Set
End Property
Public Overrides Function Validate(ByVal value As Object, ByVal cultureInfo As CultureInfo) As ValidationResult
Dim margin As Double
' Is a number?
If Not Double.TryParse(CStr(value), margin) Then
Return New ValidationResult(False, "Not a number.")
End If
' Is in range?
If ((margin < Me.MinMargin) OrElse (margin > Me.MaxMargin)) Then
Dim msg As String = String.Format("Margin must be between {0} and {1}.", Me.MinMargin, Me.MaxMargin)
Return New ValidationResult(False, msg)
End If
' Number is valid
Return New ValidationResult(True, Nothing)
End Function
End Class
End Namespace
在此程式碼中,驗證規則的驗證邏輯是藉由覆寫 Validate 方法來實作,此方法會驗證資料並傳回適當的 ValidationResult 。
若要建立驗證規則與繫結控制項的關聯,您可以使用下列標記。
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.MarginsDialogBox"
xmlns:local="clr-namespace:SDKSample"
Title="Margins"
Height="190"
Width="300"
MinHeight="10"
MinWidth="300"
ResizeMode="CanResizeWithGrip"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner"
FocusManager.FocusedElement="{Binding ElementName=leftMarginTextBox}">
<Grid>
<!-- Left Margin -->
<Label Grid.Column="0" Grid.Row="0">Left Margin:</Label>
<TextBox Name="leftMarginTextBox" Grid.Column="1" Grid.Row="0">
<TextBox.Text>
<Binding Path="Left" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:MarginValidationRule MinMargin="0" MaxMargin="10" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid >
</Window>
一旦驗證規則相關聯,WPF 就會在資料輸入繫結控制項時自動套用它。 當控制項包含不正確資料時,WPF 會在不正確控制項周圍顯示紅色框線,如下圖所示。
WPF 在使用者輸入有效資料之前,不會將使用者限制為不正確控制項。 這是很好的對話方塊行為;使用者應該能夠自由地巡覽對話方塊中的控制項,而不論資料是否有效。 不過,這表示使用者可以輸入無效的資料並按下 [確定] 按鈕。 基於這個理由,當處理 Click 事件按下 [確定 ] 按鈕時 ,您的程式碼也需要驗證對話方塊中的所有控制項。
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace SDKSample
{
public partial class MarginsDialogBox : Window
{
void okButton_Click(object sender, RoutedEventArgs e)
{
// Don't accept the dialog box if there is invalid data
if (!IsValid(this)) return;
}
// Validate all dependency objects in a window
bool IsValid(DependencyObject node)
{
// Check if dependency object was passed
if (node != null)
{
// Check if dependency object is valid.
// NOTE: Validation.GetHasError works for controls that have validation rules attached
bool isValid = !Validation.GetHasError(node);
if (!isValid)
{
// If the dependency object is invalid, and it can receive the focus,
// set the focus
if (node is IInputElement) Keyboard.Focus((IInputElement)node);
return false;
}
}
// If this dependency object is valid, check all child dependency objects
foreach (object subnode in LogicalTreeHelper.GetChildren(node))
{
if (subnode is DependencyObject)
{
// If a child dependency object is invalid, return false immediately,
// otherwise keep checking
if (IsValid((DependencyObject)subnode) == false) return false;
}
}
// All dependency objects are valid
return true;
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Input
Namespace SDKSample
Public Class MarginsDialogBox
Inherits Window
Private Sub okButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Don't accept the dialog box if there is invalid data
If Not Me.IsValid(Me) Then Return
End Sub
' Validate all dependency objects in a window
Private Function IsValid(ByVal node As DependencyObject) As Boolean
' Check if dependency object was passed and if dependency object is valid.
' NOTE: Validation.GetHasError works for controls that have validation rules attached
If ((Not node Is Nothing) AndAlso Validation.GetHasError(node)) Then
' If the dependency object is invalid, and it can receive the focus,
' set the focus
If TypeOf node Is IInputElement Then
Keyboard.Focus(DirectCast(node, IInputElement))
End If
Return False
End If
' If this dependency object is valid, check all child dependency objects
Dim subnode As Object
For Each subnode In LogicalTreeHelper.GetChildren(node)
If (TypeOf subnode Is DependencyObject AndAlso Not Me.IsValid(DirectCast(subnode, DependencyObject))) Then
' If a child dependency object is invalid, return false immediately,
' otherwise keep checking
Return False
End If
Next
' All dependency objects are valid
Return True
End Function
End Class
End Namespace
此程式碼會列舉視窗上的所有相依性物件,如果有任何相依性物件無效,則無效 GetHasError 的控制項會取得焦點, IsValid
方法會 false
傳回 ,而且視窗視為無效。
一旦對話方塊有效,就可以安全地將它關閉並傳回。 在傳回過程中,必須將結果傳回呼叫函式。
設定強制回應對話方塊結果
使用 ShowDialog 開啟對話方塊基本上就像呼叫 方法:使用 ShowDialog 等候直到傳回時 ShowDialog 開啟對話方塊的程式碼。 傳回時 ShowDialog ,呼叫它的程式碼必須根據使用者 按下 [確定 ] 按鈕或 [取消 ] 按鈕,決定是否要繼續處理或 停止處理。 為了方便此決策,對話方塊必須傳回使用者的選擇做為 Boolean 從 ShowDialog 方法傳回的值。
按一下 [ 確定] 按鈕時, ShowDialog 應該會傳回 true
。 按一下 [確定 ] 按鈕時 ,設定對話方塊的 屬性即可達成 DialogResult 此目的。
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace SDKSample
{
public partial class MarginsDialogBox : Window
{
void okButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Input
Namespace SDKSample
Public Class MarginsDialogBox
Inherits Window
Private Sub okButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Dialog box accepted
MyBase.DialogResult = New Nullable(Of Boolean)(True)
End Sub
End Class
End Namespace
請注意,設定 DialogResult 屬性也會讓視窗自動關閉,這可減輕明確呼叫 Close 的需求。
按一下 [ 取消] 按鈕時, ShowDialog 應該會傳回 false
,這也需要設定 DialogResult 屬性。
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace SDKSample
{
public partial class MarginsDialogBox : Window
{
void cancelButton_Click(object sender, RoutedEventArgs e)
{
// Dialog box canceled
this.DialogResult = false;
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Input
Namespace SDKSample
Public Class MarginsDialogBox
Inherits Window
Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Dialog box canceled
Me.DialogResult = False
End Sub
End Class
End Namespace
當按鈕的 IsCancel 屬性設定為 true
,且使用者按下 [取消 ] 按鈕或 ESC 鍵時, DialogResult 會自動設定為 false
。 下列標記的效果與上述程式碼相同,而不需要處理 Click 事件。
<Button Name="cancelButton" IsCancel="True">Cancel</Button>
當使用者按下標題列中的 [關閉] 按鈕,或從 [系統 ] 功能表中選擇 [關閉 ] 功能表項目時,對話方塊會自動傳回 false
。
處理從強制回應對話方塊傳回的資料
當 由對話方塊設定時 DialogResult ,開啟它的函式可以藉由在傳回時 ShowDialog 檢查 DialogResult 屬性來取得對話方塊結果。
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
namespace SDKSample
{
public partial class MainWindow : Window
{
void formatMarginsMenuItem_Click(object sender, RoutedEventArgs e)
{
// Process data entered by user if dialog box is accepted
if (dlg.DialogResult == true)
{
// Update fonts
this.documentTextBox.Margin = dlg.DocumentMargin;
}
}
}
}
Imports System.ComponentModel
Imports System.Windows
Imports System.Windows.Controls
Imports Microsoft.Win32
Namespace SDKSample
Public Class MainWindow
Inherits Window
Private Sub formatMarginsMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Process data entered by user if dialog box is accepted
If (dlg.DialogResult.GetValueOrDefault = True) Then
Me.documentTextBox.Margin = dlg.DocumentMargin
End If
End Sub
End Class
End Namespace
如果對話方塊結果為 true
,此函式會使用該值作為提示,以擷取及處理使用者提供的資料。
注意
傳回之後 ShowDialog ,就無法重新開啟對話方塊。 您必須改為建立新的執行個體。
如果對話方塊結果為 false
,此函式應該適當地結束處理。
建立無模式自訂對話方塊
非強制回應對話方塊 (例如下圖所示的 [尋找] 對話方塊) 與強制回應對話方塊具有相同的基本外觀。
不過,其行為稍有不同,如下列各節中所述。
開啟無強制回應對話方塊
呼叫 方法會開啟 Show 無強制回應對話方塊。
<!--Main Window-->
<MenuItem Name="editFindMenuItem" Header="_Find" InputGestureText="Ctrl+F" Click="editFindMenuItem_Click" />
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
namespace SDKSample
{
public partial class MainWindow : Window
{
void editFindMenuItem_Click(object sender, RoutedEventArgs e)
{
// Instantiate the dialog box
FindDialogBox dlg = new FindDialogBox(this.documentTextBox);
// Configure the dialog box
dlg.Owner = this;
dlg.TextFound += new TextFoundEventHandler(dlg_TextFound);
// Open the dialog box modally
dlg.Show();
}
}
}
Imports System.ComponentModel
Imports System.Windows
Imports System.Windows.Controls
Imports Microsoft.Win32
Namespace SDKSample
Public Class MainWindow
Inherits Window
Private Sub editFindMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim dlg As New FindDialogBox(Me.documentTextBox)
dlg.Owner = Me
AddHandler dlg.TextFound, New TextFoundEventHandler(AddressOf Me.dlg_TextFound)
dlg.Show()
End Sub
End Class
End Namespace
不同于 ShowDialog , Show 會立即傳回 。 因此,呼叫視窗無法得知非強制回應對話方塊何時關閉,因此不會知道何時要檢查對話方塊結果,或從對話方塊取得資料以進一步處理。 相反地,對話方塊必須建立其他方式,以將資料傳回呼叫視窗進行處理。
處理從無強制回應對話方塊傳回的資料
在此範例中, FindDialogBox
可能會根據搜尋的文字而將一或多個尋找結果傳回至主視窗,而不需要任何特定頻率。 如同強制回應對話方塊,非強制回應對話方塊可以透過屬性傳回結果。 不過,主控對話方塊的視窗必須知道何時要查看這些屬性。 其中一個做法是,讓對話方塊實作每次找到文字時所引發的事件。 FindDialogBox
會 TextFoundEvent
針對此目的實作 ,其首先需要委派。
using System;
namespace SDKSample
{
public delegate void TextFoundEventHandler(object sender, EventArgs e);
}
Namespace SDKSample
Public Delegate Sub TextFoundEventHandler(ByVal sender As Object, ByVal e As EventArgs)
End Namespace
TextFoundEventHandler
使用委派, FindDialogBox
實作 TextFoundEvent
。
using System;
using System.Windows;
using System.Windows.Controls;
using System.Text.RegularExpressions;
namespace SDKSample
{
public partial class FindDialogBox : Window
{
public event TextFoundEventHandler TextFound;
protected virtual void OnTextFound()
{
TextFoundEventHandler textFound = this.TextFound;
if (textFound != null) textFound(this, EventArgs.Empty);
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Text.RegularExpressions
Namespace SDKSample
Public Class FindDialogBox
Inherits Window
Public Event TextFound As TextFoundEventHandler
Protected Overridable Sub OnTextFound()
RaiseEvent TextFound(Me, EventArgs.Empty)
End Sub
End Class
End Namespace
因此,當找到搜尋結果時, Find
可能會引發 事件。
using System;
using System.Windows;
using System.Windows.Controls;
using System.Text.RegularExpressions;
namespace SDKSample
{
public partial class FindDialogBox : Window
{
void findNextButton_Click(object sender, RoutedEventArgs e)
{
// Text found
this.index = match.Index;
this.length = match.Length;
OnTextFound();
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Text.RegularExpressions
Namespace SDKSample
Public Class FindDialogBox
Inherits Window
Me.Index = match.Index
Me.Length = match.Length
RaiseEvent TextFound(Me, EventArgs.Empty)
End Class
End Namespace
主控視窗接著需要註冊及處理此事件。
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
namespace SDKSample
{
public partial class MainWindow : Window
{
void dlg_TextFound(object sender, EventArgs e)
{
// Get the find dialog box that raised the event
FindDialogBox dlg = (FindDialogBox)sender;
// Get find results and select found text
this.documentTextBox.Select(dlg.Index, dlg.Length);
this.documentTextBox.Focus();
}
}
}
Imports System.ComponentModel
Imports System.Windows
Imports System.Windows.Controls
Imports Microsoft.Win32
Namespace SDKSample
Public Class MainWindow
Inherits Window
Private Sub dlg_TextFound(ByVal sender As Object, ByVal e As EventArgs)
Dim dlg As FindDialogBox = DirectCast(sender, FindDialogBox)
Me.documentTextBox.Select(dlg.Index, dlg.Length)
Me.documentTextBox.Focus()
End Sub
End Class
End Namespace
關閉無強制回應對話方塊
因為 DialogResult 不需要設定,因此可以使用系統提供機制來關閉無強制回應對話方塊,包括下列專案:
按一下標題列中的 [關閉] 按鈕。
按下 ALT+F4。
從 [系統] 功能表選擇 [關閉 ]。
或者,按一下 [關閉 ] 按鈕時 ,您的程式碼可以呼叫 Close 。
using System;
using System.Windows;
using System.Windows.Controls;
using System.Text.RegularExpressions;
namespace SDKSample
{
public partial class FindDialogBox : Window
{
void closeButton_Click(object sender, RoutedEventArgs e)
{
// Close dialog box
this.Close();
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Text.RegularExpressions
Namespace SDKSample
Public Class FindDialogBox
Inherits Window
Private Sub closeButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
MyBase.Close()
End Sub
End Class
End Namespace
另請參閱
- 快顯功能表概觀
- Dialog Box Sample (對話方塊範例)
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應