WPF MessageBox вообще не отображается, если передано длинное сообщение - PullRequest
0 голосов
/ 09 ноября 2018

Я столкнулся с ситуацией, когда некоторые MessageBoxes с сообщениями об ошибках вообще не отображались.После более тщательного изучения я смог сузить проблему до случаев, когда очень длинная строка передается как messageBoxText.

В таких случаях вызов MessageBox.Show ничего не отображает, возвращает MessageBoxResult.No, и в большинстве случаев в окне Output появляется сообщение The thread 0xHEXNUMBER has exited with code 0 (0x0).Для меня этот метод молча завершается ошибкой.

Это очень странно - WPF - очень зрелая технология, и я ожидаю, что этот код будет работать в соответствии со спецификацией или вызовет какое-то исключение (например, OutOfMemory, StackOverflowException).Я отлаживал программу, и никакие управляемые или неуправляемые исключения не выбрасывались и перехватывались.

Какая основная причина MessageBox не отображается?Есть ли какой-нибудь простой способ отладки таких вещей (так как никакие исключения не выбрасываются и не регистрируются).Каково ограничение длины messageBoxText и от чего оно зависит (я мог бы проверить это эмпирически на моем компьютере, но в лучшем случае было бы убедительным для одной версии ОС / платформы / .NET Framework)?

Repro:

Вот код, демонстрирующий проблему (его можно использовать со стандартным шаблоном приложения WPF в Visual Studio).

MainWindow.xaml:

<Window x:Class="LongMessageInMessageBox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
  <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
  </Grid.ColumnDefinitions>

  <Button Grid.Row="0" Grid.Column="0" Click="ShortMessage_Clicked">Short Message</Button>
  <Button Grid.Row="1" Grid.Column="0" Click="LongMessage_Clicked">Long Message</Button>

</Grid>

MainWindow.xaml.cs:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace LongMessageInMessageBox
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        /// Method which shows that displaying short message works correctly
        private void ShortMessage_Clicked(object sender, RoutedEventArgs e)
        {
            Console.WriteLine("ShortMessage_Clicked");
            var result = MessageBox.Show("Short Message");
            Console.WriteLine(result);
        }

        /// Method which shows that displaying a long message does not work
        private void LongMessage_Clicked(object sender, RoutedEventArgs e)
        {
            Console.WriteLine("LongMessage_Clicked");
            var longTextBuilder = new System.Text.StringBuilder(10000);
            longTextBuilder.Append("Long Message \n");
            for (int i = 1; i <= 100000; i++)
            {
                longTextBuilder.Append(" ").Append(i);
            }
            var result = MessageBox.Show(longTextBuilder.ToString());
            Console.WriteLine(result);
        } 
    }
}

Образец из Output окна:

ShortMessage_Clicked
OK
ShortMessage_Clicked
OK
LongMessage_Clicked
No
The thread 0x55bc has exited with code 0 (0x0).

1 Ответ

0 голосов
/ 10 ноября 2018
Класс

MessageBox в WPF (и WinForms) оборачивает функцию Win32 MessageBox и не выдает исключение. В старом мире Win32 об ошибке сообщается установкой кода последней ошибки, и если вы не вызываете GetLastError для проверки, вы можете просто продолжать, не зная, что что-то сломано.

Из Справочный источник

//so it just translates the return code to a MessageBoxResult

MessageBoxResult result = Win32ToMessageBoxResult (UnsafeNativeMethods.MessageBox (new HandleRef (null, owner), messageBoxText, caption, style));

Я не проверял емкость строки lpText в функции Win32 MessageBox . Но неудивительно, что предел емкости составляет что-то вроде 1024, 4096 или 65536, ведь функция MessageBox предназначена для отображения коротких сообщений.

...