简体   繁体   中英

Custom WPF MessageBox text is empty

I have a custom WPF MessageBox , that upon a specific message caption is appearing in random location of the parent window. The custom MessageBox looks like this:

public static class WPFMessageBox
{
    public static MessageBoxResult Show(string messageBoxText)
    {
        return ShowCore(null, messageBoxText);
    }

    public static MessageBoxResult Show(string messageBoxText, string caption)
    {
        return ShowCore(null, messageBoxText, caption);
    }

    public static MessageBoxResult Show(Window owner, string messageBoxText)
    {
        return ShowCore(owner, messageBoxText);
    }

    public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
    {
        return ShowCore(null, messageBoxText, caption, button);
    }

    public static MessageBoxResult Show(Window owner, string messageBoxText, string caption)
    {
        return ShowCore(owner, messageBoxText, caption);
    }

    public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
    {
        return ShowCore(null, messageBoxText, caption, button, icon);
    }

    public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button)
    {
        return ShowCore(owner, messageBoxText, caption, button);
    }

    public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
    {
        return ShowCore(null, messageBoxText, caption, button, icon, defaultResult);
    }

    public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
    {
        return ShowCore(owner, messageBoxText, caption, button, icon);
    }

    public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
    {
        return ShowCore(null, messageBoxText, caption, button, icon, defaultResult, options);
    }

    public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
    {
        return ShowCore(owner, messageBoxText, caption, button, icon, defaultResult);
    }

    public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
    {
        return ShowCore(owner, messageBoxText, caption, button, icon, defaultResult, options);
    }

    private static MessageBoxResult ShowCore(
        Window owner,
        string messageBoxText,
        string caption = "",
        MessageBoxButton button = MessageBoxButton.OK,
        MessageBoxImage icon = MessageBoxImage.None,
        MessageBoxResult defaultResult = MessageBoxResult.None,
        MessageBoxOptions options = MessageBoxOptions.None)
    {
        if (caption == "specific message caption")
        {
            var maxHeight = owner.ActualHeight - 300;
            var maxWidth = owner.ActualWidth - 500;
            var randomHeight = GetRandomNumber(2, maxHeight);
            var randomWidth = GetRandomNumber(2, maxWidth);

            return WPFMessageBoxWindow.Show(
                delegate(Window messageBoxWindow)
                {
                    messageBoxWindow.WindowStartupLocation = WindowStartupLocation.Manual;
                    messageBoxWindow.Left = randomWidth;
                    messageBoxWindow.Top = randomHeight;
                    messageBoxWindow.Owner = owner;
                },
                messageBoxText, caption, button, icon, defaultResult, options);
        }

        return WPFMessageBoxWindow.Show(
            delegate(Window messageBoxWindow)
            {
                messageBoxWindow.Owner = owner;
            },
            messageBoxText, caption, button, icon, defaultResult, options);
    }

    private static double GetRandomNumber(double minimum, double maximum)
    {
        Random random = new Random();
        return random.NextDouble() * (maximum - minimum) + minimum;
    }
}

The WPF MessageBox Window looks like this :

public partial class WPFMessageBoxWindow : Window
{
    public WPFMessageBoxWindow()
    {
        InitializeComponent();
    }

    private MessageBoxViewModel _viewModel;

    public static MessageBoxResult Show(
        Action<Window> setOwner,
        string messageBoxText, 
        string caption, 
        MessageBoxButton button, 
        MessageBoxImage icon, 
        MessageBoxResult defaultResult, 
        MessageBoxOptions options)
    {
        if ((options & MessageBoxOptions.DefaultDesktopOnly) == MessageBoxOptions.DefaultDesktopOnly)
        {
            throw new NotImplementedException();
        }

        if ((options & MessageBoxOptions.ServiceNotification) == MessageBoxOptions.ServiceNotification)
        {
            throw new NotImplementedException();
        }

        _messageBoxWindow = new WPFMessageBoxWindow()
        {
            ShowInTaskbar = false,
            Topmost = true,
            ResizeMode = ResizeMode.NoResize
        };

        setOwner(_messageBoxWindow);

        PlayMessageBeep(icon);

        _messageBoxWindow._viewModel = new MessageBoxViewModel(_messageBoxWindow, caption, messageBoxText, button, icon, defaultResult, options);
        _messageBoxWindow.DataContext = _messageBoxWindow._viewModel;
        _messageBoxWindow.ShowDialog();
        return _messageBoxWindow._viewModel.Result;
    }

    private static void PlayMessageBeep(MessageBoxImage icon)
    {
        switch (icon)
        {
            //case MessageBoxImage.Hand:
            //case MessageBoxImage.Stop:
            case MessageBoxImage.Error:
                SystemSounds.Hand.Play();
                break;

            //case MessageBoxImage.Exclamation:
            case MessageBoxImage.Warning:
                SystemSounds.Exclamation.Play();
                break;

            case MessageBoxImage.Question:
                SystemSounds.Question.Play();
                break;

            //case MessageBoxImage.Asterisk:
            case MessageBoxImage.Information:
                SystemSounds.Asterisk.Play();
                break;

            default:
                SystemSounds.Beep.Play();
                break;
        }
    }

    [ThreadStatic]
    private static WPFMessageBoxWindow _messageBoxWindow;

    protected override void OnSourceInitialized(EventArgs e)
    {
        // removes the application icon from the window top left corner
        // this is different than just hiding it
        WindowHelper.RemoveIcon(this);

        switch (_viewModel.Options)
        { 
            case MessageBoxOptions.None:
                break;

            case MessageBoxOptions.RightAlign:
                WindowHelper.SetRightAligned(this);
                break;

            case MessageBoxOptions.RtlReading:
                break;

            case MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading:
                break;
        }

        // disable close button if needed and remove resize menu items from the window system menu
        var systemMenuHelper = new SystemMenuHelper(this);

        if (_viewModel.ButtonOption == MessageBoxButton.YesNo)
        {
            systemMenuHelper.DisableCloseButton = true;
        }

        systemMenuHelper.RemoveResizeMenu = true;
    }

    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Escape)
        {
            _viewModel.EscapeCommand.Execute(null);
        }
    }

    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        _viewModel.CloseCommand.Execute(null);
    }
}

This how I use the MessageBox for my specific caption in the code :

dynamic parentWindow = Window.GetWindow(this);
var result = WPFMessageBox.Show(parentWindow, "message text", "specific message cation", 
MessageBoxButton.YesNo, MessageBoxImage.Question);

My Problem is that once in a while, only for this specific message, the MessageBox text is appearing empty:

空文字

Here is the XAML :

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MessageBoxUtils"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MessageBoxUtils.WPFMessageBoxWindow"
    Title="{Binding Title}" ResizeMode="NoResize" FlowDirection="{Binding TitleFlowDirection}"
    ShowInTaskbar="False" WindowStartupLocation="CenterScreen" SizeToContent="Height" KeyDown="Window_KeyDown" Width="500" d:DesignWidth="500" Height="300">
<Grid>

    <Grid FlowDirection="{Binding ContentFlowDirection}">
        <Grid.RowDefinitions>
            <RowDefinition Height="60" />
            <RowDefinition Height="2" />
            <RowDefinition Height="*" />
            <RowDefinition Height="90" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="60" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Image Source="{Binding MessageImageSource}" HorizontalAlignment="Left" VerticalAlignment="Center" Height="32" Width="32" Margin="10 0 0 0" />

        <TextBlock FontSize="28" Text="{Binding Message}" Grid.RowSpan="3" Grid.Column="1" TextWrapping="Wrap" TextAlignment="Left" HorizontalAlignment="{Binding ContentTextAlignment}" VerticalAlignment="Top" Margin="10,10,10,0"  />

        <Border Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Background="#FFE6E6E6" BorderThickness="0 1 0 0" BorderBrush="#FFDFDFDF">
            <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,18,10,10" Height="63" >
                <Button FontSize="25" Content="_Yes" Visibility="{Binding YesNoVisibility}" Command="{Binding YesCommand}" IsDefault="{Binding IsYesDefault}" Margin="5 5 5 5" Height="42" Width="80" />
                <Button FontSize="25" Content="_No" Visibility="{Binding YesNoVisibility}" Command="{Binding NoCommand}" IsDefault="{Binding IsNoDefault}" Margin="5 5 5 5" Height="42" Width="80" />
                <Button FontSize="25" Content="O_K" Visibility="{Binding OkVisibility}" Command="{Binding OkCommand}" IsDefault="{Binding IsOkDefault}" Margin="5 5 5 5" Height="42" Width="80" />
                <Button FontSize="25" Content="_Cancel" Visibility="{Binding CancelVisibility}" Command="{Binding CancelCommand}" IsDefault="{Binding IsCancelDefault}" Margin="5 5 5 5" Height="42" Width="80" />
            </StackPanel>
        </Border>
    </Grid>


</Grid>

Is anyone knows why?

You're binding the text to a property named 'Message' but I don't see that in your VM ... Unless I've missed it!

Anyway my bet would be that you're not issuing a NotifyPropertyChanged event when that property is updated, so if the viewmodel is created before the view then the view queries the VM and all is well, however if the VM is populated a little after the view then the view will received an empty string when queried. The property is then updated in the VM, but the view never gets told about it. Just a hunch.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM