开发者

NullReferenceException when changing skin/theme via Application.Current.Resources

I am writing an wpf application with multiple skins. The code to switch theme is as below:

try
{
    Application.Current.Resources.MergedDictionaries.Add( resource );
}
catch( Exception ex )
{

}

The first time the code is called (to switch to a new theme), it is executed successfully; however, any subsequent calls to the same code would throw System.NullReferenceException.

The way I set up my themes are similar to what described here: http://www.codewrecks.com/blog/index.php/2008/05/22/simple-skinnable-and-theme-management-in-wpf-user-interface/.

Has anyone seen this error before? How do I go about debugging this since the exception is thrown else where? Any help is greatly appreciated.

StackTrace:
       at System.Windows.EffectiveValueEntry.GetFlattenedEntry(RequestFlags requests)
       at System.Windows.DependencyObject.EvaluateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry newEntry, OperationType operationType)
       at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
       at System.Windows.StyleHelper.ApplyStyleOrTemplateValue(FrameworkObject fo, DependencyProperty dp)
       at System.Windows.StyleHelper.InvalidateContainerDependents(DependencyObject container, FrugalStructList`1& exclusionContainerDependents, FrugalStructList`1& oldContainerDependents, FrugalStructList`1& newContainerDependents)
       at System.Windows.StyleHelper.DoStyleInvalidations(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle)
       at System.Windows.StyleHelper.UpdateStyleCache(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle, Style& styleCache)
       at System.Windows.FrameworkElement.OnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
       at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
       at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
       at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
       at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
       at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp)
       at System.Windows.FrameworkElement.UpdateStyleProperty()
       at System.Windows.TreeWalkHelper.InvalidateStyleAndReferences(DependencyObject d, ResourcesChangeInfo info, Boolean containsTypeOfKey)
       at System.Windows.TreeWalkHelper.OnResourcesChanged(DependencyObject d, ResourcesChangeInfo info, Boolean raiseResourceChangedEvent)
       at System.Windows.TreeWalkHelper.OnResourcesChangedCallback(DependencyObject d, ResourcesChangeInfo info)
       at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe)
       at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
       at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
       at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
       at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe)
       at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
       at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
       at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
       at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe)
       at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
       at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
       at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
       at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
       at System.Windows.Descende开发者_运维知识库ntsWalker`1.VisitNode(FrameworkElement fe)
       at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
       at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
       at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
       at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe)
       at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
       at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
       at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe)
       at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
       at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
       at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
       at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe)
       at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
       at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
       at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
       at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe)
       at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
       at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
       at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
       at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe)
       at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
       at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
       at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
       at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe)
       at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
       at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
       at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
       at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
       at System.Windows.DescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode)
       at System.Windows.TreeWalkHelper.InvalidateOnResourcesChange(FrameworkElement fe, FrameworkContentElement fce, ResourcesChangeInfo info)
       at System.Windows.Application.InvalidateResourceReferenceOnWindowCollection(WindowCollection wc, ResourcesChangeInfo info)
       at System.Windows.ResourceDictionary.NotifyOwners(ResourcesChangeInfo info)
       at System.Windows.ResourceDictionary.OnMergedDictionariesChanged(Object sender, NotifyCollectionChangedEventArgs e)
       at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
       at System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, T item)
       at System.Windows.ResourceDictionaryCollection.InsertItem(Int32 index, ResourceDictionary item)
       at System.Collections.ObjectModel.Collection`1.Add(T item)


In the same link you described above, you must first clear MergedDictionaries and then add. as following.

try 
{ 
    Application.Current.Resources.MergedDictionaries.Clear();
    Application.Current.Resources.MergedDictionaries.Add( resource ); 
} 
catch( Exception ex ) 
{ 

}

The reason you are getting errors on subsequent calls because the dictionaries maintain only one key for one resource its like hashtable and multiple keys might be creating problem if you just keep on adding different themes with same keys defined in them.


for me it was the application.current what gave null value, and that has no .resources (or .mainwindow what i actually wanted)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜