2016-07-11 13 views
0

Ich habe eine benutzerdefinierte WPF MessageBox, die nach einer bestimmten Nachricht Beschriftung in zufälliger Position des übergeordneten Fensters erscheint. Der Brauch MessageBox sieht wie folgt aus:Benutzerdefinierter WPF-MessageBox-Text ist leer

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

Diese, wie ich die MessageBox für meine spezifischen Beschriftung im Code verwenden:

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

Das WPF MessageBox-Fenster sieht wie folgt aus

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

Mein Problem ist, dass hin und wieder, nur für diese spezifische Nachricht, der MessageBox Text leer erscheint:

empty text

Hier ist die 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> 

Ist jemand weiß, warum?

+0

Gibt es einen XAML? Mit "meine spezifische Überschrift" meinst du die wörtliche Zeichenfolge '" spezifische Nachrichtenüberschrift "', die als ein Sonderfall behandelt wird? Wird das Problem dadurch behoben, dass Sie dem Meldungsfeld gestatten, in diesem Fall seine eigene Größe zu bestimmen? Verwenden Sie zufällig ein HTML-Widget, um den Nachrichtentext anzuzeigen, und übergeben Sie immer etwas zwischen spitzen Klammern, wenn Sie diese Beschriftung übergeben? –

+0

Es gibt XAML für das WPFMessageBoxWindow. Und ja, ich meine die wörtliche Zeichenfolge, die als Sonderfall behandelt wird. Das WPFMessageBoxWindow XAML bestimmt die Größe. Ich verwende kein HTML-Widget. Ich gebe immer etwas zwischen spitzen Klammern weiter, wenn ich diese Überschrift übergebe. –

+0

Sie könnten diese XAML teilen –

Antwort

0

Sie binden den Text an eine Eigenschaft namens "Message", aber ich sehe das nicht in Ihrer VM ... Es sei denn, ich habe es verpasst!

Wie auch immer meine Wette wäre, dass Sie kein NotifyPropertyChanged-Ereignis ausgeben, wenn diese Eigenschaft aktualisiert wird. Wenn also das Viewmodell vor der View erstellt wird, fragt die View die VM ab und alles ist gut, wenn die VM jedoch gefüllt ist ein wenig nach der Ansicht erhält die Ansicht eine leere Zeichenfolge, wenn sie abgefragt wird. Die Eigenschaft wird dann in der VM aktualisiert, aber die Ansicht wird nie darüber informiert. Nur eine Ahnung.