Announcement

Collapse
No announcement yet.

Eigener WPF-Dialog unter VB.NET zeigt manchmal nichts mehr an

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Eigener WPF-Dialog unter VB.NET zeigt manchmal nichts mehr an

    Hallo Entwickler,

    ich entwickle mit VB.NET und Visual Studio 2017 unter Windows 10.
    I habe einen eigenen Dialog geschrieben um einfach einen Text in einem TextBlock-Element anzuzeigen.
    Und nun das Problem: Manchmal habe ich das Problem, daß obwohl ich meinen Dialog mit einem zugewiesenen Text aufrufe,
    nur ein leeres Fenster angezeigt wird, also kein Text und auch der OK-Button wird nicht angezeigt.
    Dies passiert vor allen Dingen unter der Ausführung eines Windows7-Embedded-Betriebssystem und nach bisherigem
    Anschein nur, wenn ich die Show()-Methode benutze. Bei ShowDialog() wurde bislang immer alles wie erwartet angezeigt.
    In meinem Fall habe ich noch eine eigene Show-Methode geschrieben, welche den Dialog mittels Show zunächst anzeigt,
    dann den aktuellen Thread eine bestimmte Zeit anhalte und nach dieser Zeit den Dialog mittels der Close()-Methode wieder schließe.
    Anmerkung: Ich konstruiere und rufe den Dialog innerhalb des Main-Threads auf, also nicht von einem anderen Thread heraus.

    Hat von euch jemand schon mal solch einen merkwürdigen Effekt eines leeren Fensters gehabt?

    Hier der xaml-Code:

    <Window x:Class="AnzeigeBoxStilSaege"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Information" Height="331" Width="523" FontSize="20" SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen" Background="Gray">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <TextBlock Background="Gray" x:Name="TextDisplayBox"
    HorizontalAlignment="Center" Height="237" Margin="10,10,11,0"
    TextWrapping="Wrap" VerticalAlignment="Top" Width="474"
    IsEnabled="True" FontWeight="Bold" Foreground="Black"
    FontSize="16"/>
    </StackPanel>
    </Window>

    Und hier der Code-Behind:

    Imports System.Threading

    Public Class AnzeigeBoxStilSaege
    Private _AnzeigeText As String = String.Empty

    Public Property AnzeigeText As String
    Get
    Return TextDisplayBox.Text
    End Get
    Set(value As String)
    TextDisplayBox.Text = value
    End Set
    End Property

    Public Enum MessageBoxStyle
    Warnung = 0
    Frage
    Information
    Fehler
    Nichts
    End Enum

    Sub New(ByVal Title As String, ByVal SetAsTopMost As Boolean, ByVal TextToBeDisplayed As String, ByVal Stil As MessageBoxStyle)
    InitializeComponent()
    Me.Title = Title
    Topmost = SetAsTopMost
    SetImageOfBox(Stil)
    AnzeigeText = TextToBeDisplayed
    End Sub

    Private Sub SetImageOfBox(ByVal imageType As MessageBoxStyle)
    If imageType = MessageBoxStyle.Warnung Then
    SetImage("mb_warning_48x48.png")
    TextDisplayBox.Background = New SolidColorBrush(Color.FromArgb(255, &HF2, &HAD, &H0)) ' RGB-Wert für Warnfarbe : f2ad00 hexadezimal
    ElseIf imageType = MessageBoxStyle.Frage Then
    SetImage("mb_question_48x48.png")
    TextDisplayBox.Background = Brushes.LightBlue
    ElseIf imageType = MessageBoxStyle.Information Then
    SetImage("mb_information_48x48.png")
    TextDisplayBox.Background = Brushes.LightSteelBlue
    ElseIf imageType = MessageBoxStyle.Fehler Then
    SetImage("mb_error_48x48.png")
    TextDisplayBox.Background = Brushes.OrangeRed
    End If
    End Sub

    Private Sub SetImage(ByVal imageName As String)
    Dim uri As String = String.Format("pack://application:,,,/DialogUtils;component/Resources/Images/{0}", imageName)
    Dim uriSource As Uri = New Uri(uri, UriKind.Absolute)
    Icon = New BitmapImage(uriSource)
    End Sub


    Public Sub UpdateText(ByVal Text As String)
    AnzeigeText = Text
    End Sub

    Public Delegate Sub SetResultDelegate(mbr As Boolean)

    Public Async Function ShowDialogThreadSafeAsync() As Task(Of Boolean)
    Dim result As Boolean = False
    Dim completion As TaskCompletionSource(Of Boolean) = New TaskCompletionSource(Of Boolean)

    Try
    Dim Del As SetResultDelegate = AddressOf completion.SetResult
    result = Await Me.Dispatcher.BeginInvoke(Del, New Object() {ShowDialog()}).Result
    Catch ex As OperationCanceledException

    Catch ex As Exception

    End Try

    Return result
    End Function

    Public Function ShowDialogThreadSafe() As Boolean
    Dim result As Boolean = False
    Dim completion As TaskCompletionSource(Of Boolean) = New TaskCompletionSource(Of Boolean)

    Try
    Dim Del As SetResultDelegate = AddressOf completion.SetResult
    result = Me.Dispatcher.BeginInvoke(Del, New Object() {ShowDialog()}).Result
    Catch ex As OperationCanceledException

    Catch ex As Exception

    End Try

    Return result
    End Function

    Public Delegate Sub SetDelegate()
    Private Sub ShowNonModal()
    Me.Show()
    End Sub

    Private Sub CloseNonModal()
    Me.Close()
    End Sub
    Public Sub ShowThreadSafe()
    Try
    Dim Del As SetDelegate = AddressOf ShowNonModal
    Me.Dispatcher.BeginInvoke(Del, New Object() {})
    Catch ex As OperationCanceledException

    Catch ex As Exception

    End Try
    End Sub

    Public Sub CloseThreadSafe()
    Try
    Dim Del As SetDelegate = AddressOf CloseNonModal
    Me.Dispatcher.BeginInvoke(Del, New Object() {})
    Catch ex As OperationCanceledException

    Catch ex As Exception

    End Try
    End Sub

    Public Sub ShowTimed(ByVal AnzeigedauerInMs As Integer)
    Show()
    Me.TextDisplayBox.Focus()
    Me.btnDialogOk.Focus()
    Thread.Sleep(AnzeigedauerInMs)
    Close()
    End Sub

    Public Sub ShowTimedThreadSafe(ByVal AnzeigedauerInMs As Integer)
    ShowThreadSafe()
    Me.TextDisplayBox.Focus()
    Me.btnDialogOk.Focus()
    Thread.Sleep(AnzeigedauerInMs)
    CloseThreadSafe()
    End Sub

    Private Sub BtnDialogOk_Click(sender As Object, e As RoutedEventArgs)
    CloseThreadSafe()
    End Sub

    Protected Overrides Sub Finalize()
    MyBase.Finalize()
    End Sub

    End Class

    Mein Dialog wird letztendlich folgendermassen konstruiert und aufgerufen:

    Dim HinweisAnzeige As AnzeigeBoxStilSaege = New AnzeigeBoxStilSaege("Title", True, "Text to be displayed in textblock control", AnzeigeBoxStilSaege.MessageBoxStyle.Warnung)
    HinweisAnzeige.ShowTimed(5000)



    Vielen Dank im Voraus für eure Hilfe!

    Gruß
    Nerd77

  • #2
    Möglicherweise wird in Windows7 Embedded das zeichnen verzögert ausgeführt. Also nicht sofort in Show. Da du den Thread danach sofort anhältst wird dann auch nicht gezeichnet und bevor es zu irgendeinem zeichnen danach kommt hast du den Dialog geschlossen. Wenn das Problem nur bei dem ShowTimed Aufruf passiert kannst du ja mal Testweise das Close da rausnehmen und schauen ob dein Dialog dann nach 5 Sekunden gezeichnet wird.

    Comment


    • #3
      Ich weiß nicht, ob Dir das wirklich weiterhilft, aber ich hatte auch den Effekt, daß eine Controls nichts bzw. verzögert anzeigen. Bei mir hat ein <Control>.refresh geholfen.

      Comment

      Working...
      X