Simon: WpfDemo

Beitrag lesen

So habe mich mal rangesetzt und eine kleine Demo-Anwendung geschrieben, die sollte weiterhelfen. Einfach ein neues WPF-Projekt erstellen (WpfDemo) und folgende Daten entsprechend einfügen. Das Fenster friert nicht ein, im Hintergrund läuft ein Thread, der dann hin- und wieder Statustext ausgibt.

  
<Window x:Name="window" x:Class="WpfDemo.MainWindow"  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        Title="MainWindow" Height="286" Width="335" ResizeMode="NoResize" UseLayoutRounding="True">  
  <Grid Margin="10,10,10,10">  
    <Button Content="Start" HorizontalAlignment="Left" Margin="216,204,0,0" VerticalAlignment="Top" Width="79" Height="24" IsEnabled="{Binding AllowInput, ElementName=window, Mode=OneWay, ValidatesOnNotifyDataErrors=False}" Click="Button_Click"/>  
    <TextBox HorizontalAlignment="Left" Height="23" Margin="10,16,0,0" TextWrapping="Wrap" Text="{Binding Message, ElementName=window, Mode=TwoWay, ValidatesOnNotifyDataErrors=False}" VerticalAlignment="Top" Width="289" IsEnabled="{Binding AllowInput, ElementName=window, Mode=OneWay, ValidatesOnNotifyDataErrors=False}"/>  
    <Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="138" Margin="10,61,0,0" VerticalAlignment="Top" Width="289">  
      <TextBlock HorizontalAlignment="Left" Margin="10,10,10,10" TextWrapping="Wrap" Text="{Binding StatusText, ElementName=window, Mode=OneWay, ValidatesOnNotifyDataErrors=False}" VerticalAlignment="Top" />  
    </Border>  
  </Grid>  
</Window>  

  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading;  
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 WpfDemo  
{  
  /// <summary>  
  /// Interaktionslogik für MainWindow.xaml  
  /// </summary>  
  public partial class MainWindow : Window  
  {  
    // Design-Time  
    public static readonly DependencyProperty AllowInputProperty = DependencyProperty.Register("AllowInput", typeof(bool), typeof(MainWindow));  
    public static readonly DependencyProperty MesssageProperty = DependencyProperty.Register("Message", typeof(string), typeof(MainWindow));  
    public static readonly DependencyProperty StatusTextProperty = DependencyProperty.Register("StatusText", typeof(string), typeof(MainWindow));  
  
    internal bool AllowInput  
    {  
      get { return (bool)GetValue(AllowInputProperty); }  
      set { SetValue(AllowInputProperty, value); }  
    }  
  
    internal string Message  
    {  
      get { return (string)GetValue(MesssageProperty); }  
      set { SetValue(MesssageProperty, value); }  
    }  
  
    internal string StatusText  
    {  
      get { return (string)GetValue(StatusTextProperty); }  
      set { SetValue(StatusTextProperty, value); }  
    }  
  
    public MainWindow()  
    {  
      InitializeComponent();  
      AllowInput = true;  
      Message = "Hier Text eingeben";  
      StatusText = "";  
    }  
  
    private void Button_Click(object sender, RoutedEventArgs e)  
    {  
      AllowInput = false;  
      StatusText = "";  
  
      Task.Factory.StartNew(() =>  
      {  
        try  
        {  
          for (int i = 0; i < 5; ++i)  
          {  
            Thread.Sleep(1000); // oder was auch immer  
            InvokeUI(() => StatusText += string.Format("{0}: {1}{2}", DateTime.Now, Message, Environment.NewLine)); // Sicher  
          }  
  
          throw new Exception("Das ist ein Test");  
        }  
        catch (Exception ex)  
        {  
          Thread.Sleep(1000);  
          AddStatusText(ex.Message); // Sicher  
        }  
  
        InvokeUI(() => AllowInput = true); // Sicher  
      }, TaskCreationOptions.LongRunning);  
    }  
  
    private void InvokeUI(Action action)  
    {  
      Dispatcher.Invoke(action);  
    }  
  
    private void AddStatusText(string message)  
    {  
      InvokeUI(() => StatusText += string.Format("{0}: {1}{2}", DateTime.Now, message, Environment.NewLine));  
    }  
  }  
}