Может ли кто-нибудь придумать хорошее объяснение тому факту, что результатом диалога является нулевое логическое значение в WPF? Это всегда сбивало меня с толку. В WinForms это был тип перечисления, и это имело для меня гораздо больше смысла.
Почему DialogResult является нулевым логическим значением в WPF?
Ответы (5)
На мой взгляд, это было сделано потому, что в большинстве случаев вам не нужны обобщенные специализированные опции, такие как Повторить или Игнорировать.
Если вам нужно больше, чем OK/Cancel, вы должны использовать какое-то диалоговое окно задачи, например. с письменными ответами. Таким образом, вы не ограничены несколькими значениями перечисления, которые кто-то придумал несколько десятилетий назад, а DialogResult является просто положительным/отрицательным для базового использования, и вы можете реализовать свое собственное свойство, специфичное для ваших дополнительных потребностей. Поэтому требуется только true/false, а null означает, что окно еще не закрыто (свойству еще не присвоено значение).
Если у вас есть диалоговое окно, которое представляет собой нечто большее, чем просто вопрос, на который должен ответить пользователь (например, форма ввода), вам обычно лучше использовать OK/Cancel, поэтому вам не нужны дополнительные значения.
Свойство DialogResult
определено в классе Window
. Не все Window
являются диалогами. Поэтому это свойство не относится ко всем окнам. Window
, который был показан через Show()
, а не ShowDialog()
, будет (предположительно, если вы не установили его по какой-либо причине) иметь DialogResult = null
.
Вот простой пример для демонстрации:
Window1.xaml:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
<Button Name="b1">Show</Button>
<Button Name="b2">ShowDialog</Button>
</StackPanel>
</Window>
Window1.xaml.cs:
using System.Windows;
namespace WpfApplication1
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
b1.Click += new RoutedEventHandler(b1_Click);
b2.Click += new RoutedEventHandler(b2_Click);
}
void b1_Click(object sender, RoutedEventArgs e)
{
var w = new Window();
w.Closed += delegate
{
MessageBox.Show("" + w.DialogResult);
};
w.Show();
}
void b2_Click(object sender, RoutedEventArgs e)
{
var w = new Window();
w.ShowDialog();
MessageBox.Show("" + w.DialogResult);
}
}
}
Когда вы закроете окна, вы заметите, что диалоговое окно имеет DialogResult
из false
, а не диалоговое окно имеет null DialogResult
.
Согласно документации MSDN:
DialogResult имеет значение null, когда диалоговое окно отображается, но не принимается и не отменяется.
Но я не уверен, как это могло произойти, если вы не имеете дело с несколькими потоками, обращающимися к диалогу.
В документации говорится, что это ложь, когда происходит одно из следующих событий:
- Нажимает ALT+F4.
- Нажимает кнопку Закрыть.
- Выберите «Закрыть» в меню «Система».
Show
, то вызов возвращается к вам (т. Е. Это неблокирующий вызов), поэтому вы можете сразу же запросить значение DialogResult
. Только если вы вызываете ShowDialog
, вызов блокируется до тех пор, пока диалог не будет закрыт. Однако в последнем случае вы все равно можете опрашивать объект из другого потока, как вы указываете.
- person Drew Noakes; 06.11.2009
ShowDialog всегда будет возвращать true или false. DialogResult будет принимать нулевое состояние только тогда, когда диалоговое окно открыто. Переход от null к true или false закроет диалоговое окно и вернет исходный вызов ShowDialog.
ИМО это потому, что DialogResult не всегда используется. Видите ли, вы можете установить DialogResult только в том случае, если окно вызывается его методом ShowDialog(), если вы вызываете его с помощью его метода Show() и пытаетесь установить DialogResult на что-либо, оно вызовет исключение InvalidOperationException. Поэтому я думаю, что это причина, по которой оно может быть обнулено, если вы вызываете окно с помощью метода Show(), оно будет нулевым, если вы вызываете его с помощью ShowDialog(), это зависит от вас.