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