نظرة عامة حول مربعات الحوار

التطبيقات المستقلة عادةً يكون لديه إطار رئيسي الذي يعرض البيانات الرئيسية التي عبرها التطبيق يعمل و يكشف عن وظيفة لمعالجة تلك البيانات خلال آليات واجهة المستخدم (UI) مثل أشرطة القوائم, أشرطة الأدوات و أشرطة الحالة. قد يعرض أيضاً التطبيق غير العادي إطارات إضافية للقيام بما يلي:

  • عرض معلومات معينة إلى المستخدمين.

  • جمع المعلومات من المستخدمين.

  • كلا من عرض و جمع المعلومات.

هذه الأنواع من الإطارات تُعرف كمربعات حوار و هناك نوعين: مشروط و غير مشروط.

يتم عرض مربع حوار مشروط بواسطة دالة عندما تحتاج الدالة بيانات إضافية من المستخدم للمتابعة. لأن الدالة تعتمد على مربع حوار مشروط لجمع البيانات, مربع الحوار المشروط أيضاً يمنع المستخدم من تنشيط الإطارات الأخرى في التطبيق بينما يظل هو مفتوحاً. في معظم الحالات، مربع الحوار المشروط يسمح للمستخدم بإشارة عند قيامهم بالانتهاء من مربع الحوار المشروط عن طريق الضغط على زر موافق أو إلغاء الأمر . يشير الضغط على زر موافق إلى أن المستخدم قام بإدخال بيانات و يرغب أن تتابع الدالة المعالجة بهذه البيانات. الضغط على زر إلغاء يشير إلى أن المستخدم يريد إيقاف الدالة عن التنفيذ تمامًا. تظهر الأمثلة الشائعة من مربعات الحوار المشروطة أت تقوم بفتح, حفظ و طباعة البيانات.

مربع الحوار غير المشروط، من ناحية أخرى، لا يمنع المستخدم من تنشيط الإطارات الأخرى أثناء فتحه. على سبيل المثال، إذا أراد المستخدم البحث عن وجود كلمة معينة في مستند, سيفتح غالباً الإطار الرئيسي مربع حوار ليطلب من مستخدم ما الكلمة الذي يبحث عنها. بما أن البحث عن كلمة لا يمنع المستخدم من تحرير المستند، ومع ذلك، لا يجب أن يكون مربع الحوار مشروط. يوفر مربع الحوار غير المشروط على الأقل زر إغلاق لإغلاق مربع الحوار ، وقد يوفر أزرار إضافية لتنفيذ وظائف معينة مثل زر البحث عن التالي للبحث عن الكلمة التالية التي تطابق معايير البحث عن الكلمة.

Windows Presentation Foundation (WPF) يسمح لك بإنشاء عدة أنواع من مربعات الحوار بما في ذلك مربعات الرسائل, مربعات الحوار العامة و مربعات الحوار المخصصة. يناقش هذا الموضوع كل منهم و يوفر نموذج مربع الحوار الأمثلة المطابقة.

يشتمل هذا الموضوع على الأقسام التالية.

  • مربعات الرسائل
  • مربعات الحوار الشائعة
  • مربعات الحوار المخصصة.
  • موضوعات ذات صلة

مربعات الرسائل

مربع الرسالة هو مربع الحوار الذي يمكن استخدامه لعرض معلومات نصية و السماح للمستخدمين بأخذ قرارات بالأزرار. يظهر الشكل التالي مربع رسالة الذي يعرض معلومات نصية, يسأل سؤال و يوفر للمستخدم ثلاثة أزرار للإجابة على السؤال.

مربع الحوار "معالج الكلمات"

لإنشاء صندوق رسالة، يمكنك استخدام MessageBoxفئة. MessageBox lets you تكوين the رسالة صندوق نص, عنوان, رمز, و الأزرار, using تعليمات برمجية مثل the following.

' 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
// 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;

لإظهار مربع رسالة, تقوم باستدعاء أسلوب static Show كما هو موضح في التعليمات البرمجية التالية.

' Display message box
MessageBox.Show(messageBoxText, caption, button, icon)
// Display message box
MessageBox.Show(messageBoxText, caption, button, icon);

عندما تحتاج التعليمات البرمجية التي يظهر مربع الرسالة إلى الكشف عن و معالجة قرار المستخدم (تم الضغط على أي زر) ، يمكن للتعليمات البرمجية فحص نتيجة مربع الرسالة كما هو موضح في التعليمات البرمجية التالية.

' 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
// 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;
}

للحصول على مزيد من المعلومات حول استخدام مربعات الرسائل, راجع MessageBox ، نموذج مربع SampleDialog MessageBox و نموذج مربع الحوار.

على الرغم من أن MessageBox قد يقدم خبرة مستخدم مربع الحوار بسيطة، ميزة استخدام MessageBox هو أنه النوع الوحيد من الإطار الذي يمكن عرضه بواسطة التطبيقات التي يتم تشغيلها ضمن حماية أمان الثقة الجزئية (راجع أمن WPF) ، مثل تطبيقات مستعرض XBAP (XBAP).

معظم مربعات الحوار تعرض و تجمع بيانات أكثر تعقيداً من نتيجة مربع الرسالة بما في ذلك النص, التحديد (خانات الاختيار), التحديد التبادلي (أزرار الخيارات) و تحديد قائمة (قائمة مربعات, مربعات التحرير والسرد و مربعات القائمة المنسدلة). لهذه ، يوفر Windows Presentation Foundation (WPF) عدة مربعات حوار عامة و يسمح لك بإنشاء مربعات الحوار الخاصة بك على الرغم من أن يقتصر استخدام كلاهما على التطبيقات التي تعمل بكامل الثقة.

مربعات الحوار الشائعة

Windows يقوم بتطبيق العديد من مربعات الحوار القابلة لإعادة الاستخدام المشتركة بين كافة التطبيقات، بما فيها مربعات الحوار لفتح الملفات, حفظ الملفات و الطباعة. حيث أنه يتم تطبيق مربعات الحوار هذه من قبل نظام التشغيل ، يمكن مشاركتهم بين كافة التطبيقات التي تعمل على نظام التشغيل التي تساعد في تماسك خبرة المستخدم; عندما يكون المستخدمين معتادين إلى استخدام مربع حوار المتوفر من قبل نظام التشغيل في تطبيق واحد , لا يحتاجوا إلى التعرف على كيفية استخدام مربع الحوار هذا في التطبيقات الأخرى. بسبب توفر مربعات الحوار إلى كافة التطبيقات و نظرًا لأنها تساعد في تقديم تجربة ثابتة للمستخدم, يتم تعريفهم باسم مربعات الحوار العامة.

يقوم Windows Presentation Foundation (WPF) بتغليف مربعات حوار فتح الملف, حفظ الملف و الطباعة الشائعة و يكشفهم كفئات مدارة لتستخدمها في التطبيقات المستقلة. يوفر هذا الموضوع نظرة عامة حول موجز كل منهم.

فتح مربع حوار ملف

يتم استخدام مربع حوار فتح الملف الموضح في الشكل التالي من قبل وظيفة فتح الملف لاسترداد اسم ملف المراد فتحه.

مربع الحوار "فتح"

مربع حوار فتح الملف الشائع يتم تطبيقه كفئة OpenFileDialog و يقع في مساحة اسم Microsoft.Win32. التعليمات البرمجية التالية توضح كيفية إنشاء , تكوين و إظهار أحد ، و كيفية معالجة النتيجة.

' 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
// 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;
}

للحصول على مزيد من المعلومات حول مربع حوار فتح الملف، راجع Microsoft.Win32.OpenFileDialog.

ملاحظةملاحظة

يمكن استخدام OpenFileDialog لاسترداد أسماء الملفات بأمان من قبل التطبيقات التي تعمل بثقة جزئية (راجع أمن WPF).

مربع حوار حفظ الملف

يتم استخدام مربع حوار حفظ الملف الموضح في الشكل التالي من قبل وظيفة حفظ الملف لاسترداد اسم ملف المراد حفظه.

مربع الحوار "حفظ باسم"

مربع حوار حفظ الملف الشائع يتم تطبيقه كفئة SaveFileDialog, و يقع في مساحة اسم Microsoft.Win32. التعليمات البرمجية التالية توضح كيفية إنشاء , تكوين و إظهار أحد ، و كيفية معالجة النتيجة.

' Configure save file dialog box
Dim dlg As New Microsoft.Win32.SaveFileDialog()
dlg.FileName = "Document" ' Default file name
dlg.DefaultExt = ".text" ' 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
// Configure save file dialog box
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".text"; // 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;
}

للحصول على مزيد من المعلومات حول مربع حوار حفظ الملف، راجع Microsoft.Win32.SaveFileDialog.

مربع حوار طباعة

يتم استخدام مربع حوار الطباعة الموضح في الشكل التالي بواسطة وظائف الطباعة لاختيار و تكوين الطابعة التي يرغب المستخدم في طباعة البيانات إليها.

مربع الحوار "طباعة"

مربع حوار طباعة الملف الشائع يتم تطبيقه كفئة PrintDialog, و يقع في مساحة اسم System.Windows.Controls. التعليمات البرمجية التالية توضح كيفية إنشاء , تكوين و إظهار أحد.

' 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
// 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
}

للحصول على مزيد من المعلومات حول مربع حوار الطباعة، راجع System.Windows.Controls.PrintDialog. للحصول على مناقشة مفصلة حول الطباعة في WPF, راجع نظرة عامة حول الطباعة.

مربعات الحوار المخصصة.

بينما مربعات الحوار العامة مفيدة و يجب استخدامها عند الإمكان ، فإنها لا تدعم متطلبات مربعات الحوار الخاصة بالمجال. في هذه الحالات، تحتاج إلى إنشاء مربعات الحوار الخاصة بك. كما أننا سوف ترى مربع حوار عبارة عن إطار بسلوك خاص. Window implements those السلوكيات و, consequently, you استخدم Window إلى إنشاء مخصص modal و modeless حوار boxes.

إنشاء مربع حوار مخصص مشروط

يوضح هذا الموضوع كيف يتم استخدام Window لإنشاء تنفيذ مربع حوار مشروط نموذجي, باستخدام مربع حوار Margins كمثال (راجع نموذج مربع الحوار ). مربع حوار Margins هو موضح في الشكل التالي.

مربع الحوار "هوامش"

تكوين مربع حوار مشروط

واجهة المستخدم لمربع الحوار النموذجي يتضمن ما يلي:

  • عناصر التحكم المتنوعة المطلوبة لتجميع البيانات المطلوبة.

  • إظهار زر موافق الذي ينقر فوقه المستخدمين لإغلاق مربع الحوار و الرجوع إلى الدالة، ومتابعة المعالجة.

  • إظهار زر إلغاء الأمر الذي ينقر فوقه المستخدم لإغلاق مربع الحوار و توقف الدالة من أي معالجة إضافية.

  • إظهار زر إغلاق في شريط العنوان.

  • إظهار رمز.

  • إظهار أزرار تصغير و تكبير و استعادة.

  • إظهار قائمة النظام لتصغير, تكبير, استعادة و إغلاق مربع الحوار.

  • فتح أعلاه و في وسط الإطار الذي فتح مربع الحوار.

  • يجب أن تكون مربعات الحوار قابلة لتغيير حجمها كلما أمكن ذلك, لمنع مربع الحوار من أن يكون صغير جداً و لتوفر للمستخدم حجم افتراضي مفيد تحتاج إلى تعيين الأبعاد الافتراضية و أدنى أبعاد على التوالي.

  • يجب أن يتم تكوين ضغط مفتاح ESC كاختصار لوحة مفاتيح الذي يؤدي إلى ضغط زر إلغاء. يتم إنجاز هذا بواسطة إعداد خاصية IsCancel من زر إلغاء الأمر إلى true.

  • يجب أن يتم تكوين ضغط مفتاح ENTER (أو RETURN) كاختصار لوحة مفاتيح الذي يؤدي إلى ضغط زر موافق. يتم إنجاز هذا بواسطة إعداد خاصية IsDefault من زر موافق true.

توضح التعليمات البرمجية التالية هذا التكوين:


<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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>
Imports System.Windows ' Window, RoutedEventArgs, IInputElement, DependencyObject
Imports System.Windows.Controls ' Validation
Imports System.Windows.Input ' Keyboard

Namespace SDKSample


Public Class MarginsDialogBox
    Inherits Window
    Public Sub New()
        Me.InitializeComponent()
    End Sub


...


End Class

End Namespace
using System.Windows; // Window, RoutedEventArgs, IInputElement, DependencyObject
using System.Windows.Controls; // Validation
using System.Windows.Input; // Keyboard

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {
        public MarginsDialogBox()
        {
            InitializeComponent();
        }


...


    }
}

خبرة المستخدم لمربع الحوار أيضاً تتوسع إلى شريط القائمة من الإطار الذي يفتح مربع الحوار. عندما يقوم عنصر قائمة بتشغيل دالة تتطلب تدخل المستخدم من خلال مربع حوار قبل أن يمكن للدالة المتابعة، عنصر القائمة الخاص بالدالة سيكون لديه حذف في العنوان الخاص به، كما هو موضح هنا.

<!--Main Window-->


...


<MenuItem Name="formatMarginsMenuItem" Header="_Margins..." Click="formatMarginsMenuItem_Click" />

عندما يتم يقوم عنصر القائمة بتشغيل دالة التي تعرض مربع الحوار الذي لا يتطلب تدخل المستخدم مثل مربع حوار حول, لا يكون مطلوباً الحذف.

فتح مربع حوار مشروط

عادةً يتم عرض مربع حوار نتيجة اختيار المستخدم لعنصر قائمة لتنفيذ دالة خاصة بالمجال مثل تعيين هوامش مستند في معالج النصوص. إظهار إطار كمربع حوار هو مشابه لإظهار إطار عادي ، على الرغم من أنه يتطلب تكوين خاص بمربع الحوار إضافي. العملية الكاملة لإنشاء, تكوين و فتح مربع الحوار موضحة في التعليمات البرمجية التالية.


Imports System '  EventArgs
Imports System.ComponentModel '  CancelEventArgs
Imports System.Windows '  Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls '  TextChangedEventArgs
Imports Microsoft.Win32 '  OpenFileDialog

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
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog

namespace SDKSample
{
    public partial class MainWindow : Window
    {


...


        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();



...


}


...


    }
}

هنا، تقوم التعليمات البرمجية بتمرير المعلومات الافتراضية (الهوامش الحالية) إلى مربع الحوار. تقوم أيضاً بتعيين خاصية Window.Owner بمرجع إلى الإطار الذي يعرض مربع الحوار. بشكل عام، يجب عليك دوماً تعيين مالك لمربع الحوار لتوفير سلوكيات ذات الصلة بحالة الإطار المشتركة في كافة مربعات الحوار (راجع نظرة عامة حول Windows WPF للمزيد من المعلومات).

ملاحظةملاحظة

يجب توفير مالك لدعم التنفيذ التلقائي واجهة المستخدم (UI) لمربعات الحوار (راجع نظرة عامة حول واجهة المستخدم التنفيذ التلقائي).

بعد تكوين مربع الحوار، يتم إظهاره مشروط عن طريق استدعاء أسلوب ShowDialog.

التحقق من صحة البيانات الموفرة بواسطة المستخدم

عندما يتم فتح مربع حوار و يوفر المستخدم البيانات المطلوبة، مربع الحوار يكون مسؤولاً عن ضمان صحة البيانات المتوفرة للأسباب التالية:

  • من منظور الأمان, يجب التحقق من كافة الإدخال.

  • من المنظور الخاص بالمجال, يمنع التحقق من الصحة معالجة البيانات الخاطئة بواسطة التعليمات البرمجية، والتي يحتمل أن تلقي الاستثناءات.

  • من منظور خبرة المستخدم, يساعد مربع الحوار المستخدمين عن طريق إظهار أي بيانات قاموا بإدخالها غير صالحة.

  • من منظور الأداء, التحقق من البيانات في تطبيق متعدد المستويات يمكن أن يقلل عدد الجولات بين العميل و مستويات التطبيق, بشكل خاص عندما يتكون التطبيق من خدمات الويب أو قواعد بيانات المستندة إلى الملقم.

للتحقق من صحة عنصر تحكم منضم في WPF، تحتاج إلى تعريف قاعدة التحقق من صحة و إقرانها مع الربط. قاعدة التحقق من صحة هي فئة مخصصة مشتقة من ValidationRule. يظهر المثال التالي قاعدة التحقق من الصحة, MarginValidationRule، التي تتحقق من أن قيمة الربط هي Double و هي ضمن النطاق المحدد.

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
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);
        }
    }
}

في هذه التعليمات البرمجية يتم تنفيذ منطق التحقق من الصحة من قاعدة التحقق من الصحة بواسطة تجاوز أسلوب Validate الذي يتحقق من صحة البيانات و يقوم بإرجاع ValidationResult المناسب.

لإقران قاعدة التحقق من الصحة مع عنصر تحكم منضم يجب استخدام العلامات التالية.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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>
    


...


<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>


...


</Window>

بمجرد اقتران قاعدة التحقق من الصحة, WPF سيطبَّقها تلقائياً عندما يتم إدخال البيانات في عنصر التحكم المنضم. عندما يحتوي عنصر تحكم على بيانات غير صالحة، WPF سيعرض حد أحمر حول عنصر تحكم غير الصحيح كما هو موضح في الشكل التالي.

هامش أيسر غير صالح

WPF لا يقيد المستخدم إلى عنصر تحكم غير صحيح حتى يقوم بإدخال بيانات صالحة. هذا هو سلوك جيد لمربع حوار; يجب أن يكون المستخدم قادراً على التنقل بحرية بين عناصر التحكم الموجودة في مربع حوار إذا كانت البيانات صالحة أم لا. مع ذلك، هذا يعني أنه يمكن للمستخدم إدخال بيانات غير صحيحة ثم الضغط على زر موافق. لهذا السبب، التعليمات البرمجية أيضاً تحتاج إلى التحقق من صحة كافة عناصر التحكم في مربع الحوار عند الضغط على زر موافق بواسطة معالجة حدث Click.

Imports System.Windows ' Window, RoutedEventArgs, IInputElement, DependencyObject
Imports System.Windows.Controls ' Validation
Imports System.Windows.Input ' Keyboard

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
using System.Windows; // Window, RoutedEventArgs, IInputElement, DependencyObject
using System.Windows.Controls; // Validation
using System.Windows.Input; // Keyboard

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;
        }
    }
}

هذه التعليمات البرمجية تعد كافة الكائنات التبعية على الإطار و إذا كان أي منها غير صالحة (كما تم إرجاعها بواسطة GetHasError، يحصل عنصر التحكم غير الصالح على التركيز, يقوم أسلوب IsValid بإرجاع false ، و يعتبر الإطار غير صالح.

بمجرد أن يكون مربع حوار الصالح, يمكن غلقه بأمان و العودة. كجزء من عملية الإرجاع, يحتاج لرجوع نتيجة إلى الدالة التي قامت بالاستدعاء.

إعداد نتيجة مربع حوار مشروط

فتح مربع حوار باستخدام ShowDialog يشبه بشكل أساسي استدعاء أسلوب: التعليمات البرمجية التي تفتح مربع الحوار باستخدام ShowDialog تنتظر حتى يرجع ShowDialog. عندما يرجع ShowDialog، التعليمات البرمجية التي قامت باستدعائها تحتاج إلى تحديد ما إذا كان يجب متابعة المعالجة أو إيقاف المعالجة ، استناداً إلى إذا قام المستخدم بالضغط على زر موافق أو زر إلغاء. لتسهيل هذا القرار ، يحتاج مربع الحوار إلى إرجاع خيار المستخدم كقيمة Boolean التي تم إرجاعها من أسلوب ShowDialog.

عند الضغط على زر موافق, ShowDialog يجب أن يرجع true. يتم إنجاز هذا بواسطة إعداد خاصية DialogResult من مربع الحوار متى تم النقر فوق زر موافق.

لاحظ أن إعداد خاصية DialogResult يؤدي أيضاً إلى إغلاق الإطار تلقائياً، الذي يخفف الحاجة إلى الاستدعاء بوضوح Close.

عند النقر على زر إلغاء الأمر، يجب أن يقوم ShowDialog بإرجاع false ، الذي يتطلب أيضاً إعداد خاصية DialogResult.

Imports System.Windows ' Window, RoutedEventArgs, IInputElement, DependencyObject
Imports System.Windows.Controls ' Validation
Imports System.Windows.Input ' Keyboard

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
using System.Windows; // Window, RoutedEventArgs, IInputElement, DependencyObject
using System.Windows.Controls; // Validation
using System.Windows.Input; // Keyboard

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {


...


void cancelButton_Click(object sender, RoutedEventArgs e)
{
    // Dialog box canceled
    this.DialogResult = false;
}


...


    }
}

عند يتم تعيين خاصية IsCancel لأحد الأزرار إلى true و يقوم المستخدم بالضغط إما على زر إلغاء أو مفتاح ESC, DialogResult يتم تعيينه تلقائياً إلى false. العلامات التالية لها نفس تأثير التعليمات البرمجية السابقة دون الحاجة إلى معالجة حدث Click.

<Button Name="cancelButton" IsCancel="True">Cancel</Button>

يرجع مربع الحوار false تلقائياً عندما يضغط مستخدم على زر إغلاق في شريط العنوان أو يختار عنصر القائمة إغلاق من قائمة النظام.

معالجة البيانات التي يتم إرجاعها من مربع حوار مشروط

عندما يتم تعيين DialogResult بواسطة مربع حوار, الدالة التي قامت بفتحه يمكنها الحصول على نتيجة مربع الحوار عن طريق اختبار خاصية DialogResult عند رجوع ShowDialog.


Imports System '  EventArgs
Imports System.ComponentModel '  CancelEventArgs
Imports System.Windows '  Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls '  TextChangedEventArgs
Imports Microsoft.Win32 '  OpenFileDialog

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
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog

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;
    }
}


...


    }
}

إذا كان ناتج مربع الحوار هو true ، تستخدم الدالة ذلك كإشارة لاسترداد البيانات التي تم توفيرها من قبل المستخدم و معالجتها.

ملاحظةملاحظة

بعد إرجاع ShowDialog, لا يمكن إعادة فتح مربع الحوار.بدلاً من ذلك، تحتاج الى إنشاء مثيل جديد.

إذا كان ناتج مربع الحوار هو false ، يجب أن تنهي الدالة المعالجة بشكل مناسب.

إنشاء مربع حوار مخصص غير مشروط

مربع حوار غير مشروط, مثل مربع حوار البحث الموضح في الشكل التالي له نفس المظهر الأساسية كمربع الحوار المشروط.

مربع الحوار "بحث"

ومع ذلك، يختلف السلوك قليلاً, كما هو موضح في المقاطع التالية.

فتح مربع حوار غير مشروط

يتم فتح مربع حوار غير مشروط باستدعاء أسلوب Show.

<!--Main Window-->

Imports System '  EventArgs
Imports System.ComponentModel '  CancelEventArgs
Imports System.Windows '  Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls '  TextChangedEventArgs
Imports Microsoft.Win32 '  OpenFileDialog

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
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog

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();
}


...


    }
}

بعكس ShowDialog، Show يرجع مباشرة. وبالتالي، لا يمكن للإطار الذي قام بالاستدعاء معرفة عندما يتم إغلاق مربع الحوار غير المشروط ، ولذلك، لا تعرف متى تتحقق من نتيجة مربع حوار أو الحصول على البيانات من مربع الحوار لمعالجة بشكل أكبر. بدلاً من ذلك، يحتاج مربع الحوار إلى إنشاء طريقة بديلة لإرجاع البيانات إلى الإطار المستدعى للمعالجة.

معالجة البيانات التي يتم إرجاعها من مربع حوار غير مشروط

في هذا المثال، قد يرجع FindDialogBox واحد أو أكثر من نتائج إلى الإطار الرئيسي ، اعتماداً على النص الذي يتم البحث عنه دون أي تردد محدد. كما هو مع مربع الحوار المشروط, يمكن لمربع الحوار غير المشروط إرجاع النتائج باستخدام الخصائص. مع ذلك، الإطار الذي يملك مربع الحوار يحتاج إلى معرفة متى يتم التحقق من هذه الخصائص. واحد way إلى تمكين this هو for the حوار صندوق إلى implement an حدث that هو مرفوع whenever نص هو found. FindDialogBoxيطبقTextFoundEventلهذا الغرض، مما أولاً يتطلب المفوض.

Namespace SDKSample
Public Delegate Sub TextFoundEventHandler(ByVal sender As Object, ByVal e As EventArgs)
End Namespace
using System;
namespace SDKSample
{
    public delegate void TextFoundEventHandler(object sender, EventArgs e);
}

باستخدام تفويض TextFoundEventHandler، FindDialogBox يطبّق TextFoundEvent.

Imports System ' EventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextBox, TextChangedEventArgs
Imports System.Text.RegularExpressions ' Regex

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
using System; // EventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextBox, TextChangedEventArgs
using System.Text.RegularExpressions; // Regex

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);
        }


...


    }
}

وبالتالي، Find يمكنه رفع الحدث عند العثور على نتائج البحث.

Imports System ' EventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextBox, TextChangedEventArgs
Imports System.Text.RegularExpressions ' Regex

Namespace SDKSample

Public Class FindDialogBox
    Inherits Window


...


Private Sub findNextButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)


...


Me.Index = match.Index
Me.Length = match.Length
RaiseEvent TextFound(Me, EventArgs.Empty)


...


End Sub


...


End Class

End Namespace
using System; // EventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextBox, TextChangedEventArgs
using System.Text.RegularExpressions; // Regex

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 '  EventArgs
Imports System.ComponentModel '  CancelEventArgs
Imports System.Windows '  Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls '  TextChangedEventArgs
Imports Microsoft.Win32 '  OpenFileDialog

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
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog

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();
        }
    }
}

إغلاق مربع حوار غير مشروط

لأن DialogResult لا يحتاج أن يتم تعيينه ، يمكن إغلاق مربع حوار غير مشروط باستخدام آليات الموفرة من النظام, تتضمن ما يلي:

  • النقر فوق زر إغلاق في شريط العنوان.

  • الضغط على ALT+F4.

  • اختيار إغلاق من قائمة النظام.

بدلاً من ذلك التعليمات البرمجية الخاصة بك يمكن أن تقوم باستدعاء Close عند النقر فوق زر إغلاق.

Imports System ' EventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextBox, TextChangedEventArgs
Imports System.Text.RegularExpressions ' Regex

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
using System; // EventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextBox, TextChangedEventArgs
using System.Text.RegularExpressions; // Regex

namespace SDKSample
{
    public partial class FindDialogBox : Window
    {


...


        void closeButton_Click(object sender, RoutedEventArgs e)
        {
            // Close dialog box
            this.Close();
        }
    }
}

راجع أيضًا:

المبادئ

نظرة عامة على الإطار المنبثق

موارد أخرى

نموذج مربع حوار

نموذج عنصر تحكم ColorPicker المخصص