Diese kleine, unscheinbare Zeile hat mich gerade einige Stunden gekostet:
<Separator Margin="5,30,5,10"/>
In einer Applikation, wird ein Fenster in einem eigenen Thread geöffnet. Auf dem Entwicklungsrechner mit Visual Studio 2012 kann ich das Fenster mit diesem Separator - Control problemlos mit .Show() anzeigen lassen. Starte ich die Applikation jedoch auf einem "normalen" Rechner, so fliegt mir der Aufruf der .Show() Methode immer um die Ohren mit:
System.Windows.Markup.XamlParseException --> System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
System.Windows.Markup.XamlParseException: The calling thread cannot access this object because a different thread owns it. ---> System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it. at System.Windows.Threading.Dispatcher.VerifyAccess() at System.Windows.Media.GradientStopCollection.OnInheritanceContextChangedCore(EventArgs args) at System.Windows.DependencyObject.OnInheritanceContextChanged(EventArgs args) at System.Windows.DependencyObject.OnInheritanceContextChanged(EventArgs args) at System.Windows.DependencyObject.ProvideSelfAsInheritanceContext(DependencyObject doValue, DependencyProperty dp) at System.Windows.FrameworkTemplate.ReceivePropertySet(Object targetObject, XamlMember member, Object value, DependencyObject templatedParent) at System.Windows.FrameworkTemplate.<>c__DisplayClass6.<LoadOptimizedTemplateContent>b__4(Object sender, XamlSetValueEventArgs setArgs) at System.Xaml.XamlObjectWriter.OnSetValue(Object eventSender, XamlMember member, Object value) at System.Xaml.XamlObjectWriter.SetValue(Object inst, XamlMember property, Object value) at System.Xaml.XamlObjectWriter.Logic_ApplyPropertyValue(ObjectWriterContext ctx, XamlMember prop, Object value, Boolean onParent) at System.Xaml.XamlObjectWriter.Logic_DoAssignmentToParentProperty(ObjectWriterContext ctx) at System.Xaml.XamlObjectWriter.WriteEndMember() at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter) --- End of inner exception stack trace --- at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter) at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlObjectWriter objectWriter) at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(DependencyObject container, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField) at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren) at System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate) at System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container) at System.Windows.FrameworkElement.ApplyTemplate() at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Controls.StackPanel.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint) at System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Documents.AdornerDecorator.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Controls.Border.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Window.MeasureOverrideHelper(Size constraint) at System.Windows.Window.MeasureOverride(Size availableSize) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Interop.HwndSource.SetLayoutSize() at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value) at System.Windows.Window.SetRootVisualAndUpdateSTC() at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight) at System.Windows.Window.CreateSourceWindow(Boolean duringShow) at System.Windows.Window.ShowHelper(Object booleanBox) at xxx.xxx.CommandMgmt.MethodParsing.MethodParserController.<>c__DisplayClass1.<ShowMethodInfo>b__0() in c:\dev\xxx\xxx\branches\v0.3\sources\Core\CommandMgmt\MethodParsing\MethodParserController.cs:line 180
Was ich überhaupt nicht verstehe, warum knallt das nur auf dem Rechner ohne das Visual Studio und was ist die genaue Ursache dafür? In dem Dialog sind Label, Button, TextBox und Progressbar - Controls, die alle nicht stören. Nur das Separator - Control verursacht diesen Fehler.
Als Workaround kann ich den Separator einfach weglassen, aber ich würde schon gerne verstehen, was da passiert.
Manchmal sind die Welten von XAML unergründlich. Ich kann Dir nicht sagen, warum das Separator Control dieses Problem verursacht. Bevor wir uns hier mit Dispatcher und UI Threads auseinandersetzen, hast Du mal ein Workaround mit nem Canvas Control getestet. Ein Separator Control müsste etwa
Scheinbar ist das ein .NET 4.0 - Bug, der mit .NET 4.5 behoben wurde! Auf den Entwicklungsrechner ist - bedingt durch VS 2012 - schon das .NET 4.5 installiert gewesen. Auf dem Geräterechner war "nur" das .NET 4.0 installiert.
Ich habe den Seperator wieder verwendet => Absturz mit .NET 4.0 Update auf .NET 4.5 durchgeführt, ohne Neustart, etc. => Programm läuft fehlerfrei durch
guter Tipp, das Canvas funktioniert. Auch wenn ich da als Hintergrund z. B. einen LinearGradientBrush verwende.
Aber ich würde ja schon gerne verstehen, was da passiert. ;) Vor allem, da es auf dem Entwicklungsrechner läuft und auf dem normalen Rechner nicht ...