Hi,
In my WPF based project, I am using a WPF Expander control, which is by default assigned a Style in XAML as seen below:
<Expander IsExpanded="False" x:Name="epdTest" Expanded="epd_Expanded" Style="{StaticResource ExpandCollapsePanelStylePlusMinusWOImage}" FontSize="13" VerticalContentAlignment="Stretch" HorizontalAlignment="Stretch">
After running the code, on certain condition we need to change the style in code behind (C#), which we are trying to do using following line:
epdTest.Style = (Style)FindResource("ExpandCollapsePanelStylePlusMinus");
Above works fine in case I have not expanded/collapsed the Expander before executing the above statement. But in case I first expand/collapse the expander, and then try to assign style from code behind as above, then it throws the below exception:
System.ArgumentNullException was caught Message=Value cannot be null. Parameter name: defaultDestinationValue Source=PresentationCore ParamName=defaultDestinationValue StackTrace: at System.Windows.Media.Animation.DoubleAnimationBase.GetCurrentValue(Object defaultOriginValue, Object defaultDestinationValue, AnimationClock animationClock) at System.Windows.Media.Animation.AnimationLayer.GetCurrentValue(Object defaultDestinationValue) at System.Windows.Media.Animation.AnimationStorage.GetCurrentPropertyValue(AnimationStorage storage, DependencyObject d, DependencyProperty dp, PropertyMetadata metadata, Object baseValue) at System.Windows.Media.Animation.AnimationStorage.EvaluateAnimatedValue(PropertyMetadata metadata, EffectiveValueEntry& entry) at System.Windows.UIElement.EvaluateAnimatedValueCore(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry& entry) 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, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp) at System.Windows.StyleHelper.InvalidatePropertiesOnTemplateNode(DependencyObject container, FrameworkObject child, Int32 childIndex, FrugalStructList`1& childRecordFromChildIndex, Boolean isDetach, FrameworkElementFactory templateRoot) at System.Windows.StyleHelper.ClearTemplateChain(HybridDictionary[] instanceData, FrameworkElement feContainer, FrameworkContentElement fceContainer, List`1 templateChain, FrameworkTemplate oldFrameworkTemplate) at System.Windows.StyleHelper.ClearGeneratedSubTree(HybridDictionary[] instanceData, FrameworkElement feContainer, FrameworkContentElement fceContainer, FrameworkTemplate oldFrameworkTemplate) at System.Windows.StyleHelper.DoTemplateInvalidations(FrameworkElement feContainer, FrameworkTemplate oldFrameworkTemplate) at System.Windows.Controls.Control.OnTemplateChanged(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, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.InvalidateProperty(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, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal) at System.Windows.FrameworkElement.set_Style(Style value)
It appears from the above exception that the error occurs somewhere due to the DoubleAnimationBase property, which we have used in the original style as below:
<Style TargetType="{x:Type Expander}" x:Key="ExpandCollapsePanelStylePlusMinusWOImage" BasedOn="{StaticResource {x:Type Expander}}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Expander}" ><DockPanel><ToggleButton x:Name="ExpanderButton" DockPanel.Dock="Top" Template="{StaticResource SimpleExpanderButtonWOImage}" Content="{TemplateBinding Header}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" OverridesDefaultStyle="True" Foreground="Black" Padding="1.5,1"></ToggleButton><ScrollViewer x:Name="ExpanderContentScrollView" DockPanel.Dock="Bottom" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Bottom"><ScrollViewer.Tag><sys:Double>0.0</sys:Double></ScrollViewer.Tag><ScrollViewer.Height><MultiBinding Converter="{StaticResource multiplyConverter}"><Binding Path="ActualHeight" ElementName="ExpanderContent"/><Binding Path="Tag" RelativeSource="{RelativeSource Self}" /></MultiBinding></ScrollViewer.Height><ContentPresenter x:Name="ExpanderContent" ContentSource="Content"/></ScrollViewer></DockPanel><ControlTemplate.Triggers><Trigger Property="IsExpanded" Value="True"><Setter Property="Foreground" Value="White" TargetName="ExpanderButton"/><Trigger.EnterActions><BeginStoryboard><Storyboard><DoubleAnimation Storyboard.TargetName="ExpanderContentScrollView" Storyboard.TargetProperty="Tag" To="1" Duration="0:0:0.4"/></Storyboard></BeginStoryboard></Trigger.EnterActions><Trigger.ExitActions><BeginStoryboard><Storyboard><DoubleAnimation Storyboard.TargetName="ExpanderContentScrollView" Storyboard.TargetProperty="Tag" To="0" Duration="0:0:0.4"/></Storyboard></BeginStoryboard></Trigger.ExitActions></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style>
If I comment the DoubleAnimation tag in above code, then it works just fine. But then it doesn't serve any purpose to me, because I need to expand/collapse the panel in slow motion (i.e. animation), which I am achieving using the DoubleAnimation.
The difference between above style "ExpandCollapsePanelStylePlusMinusWOImage", and new style which I am trying to apply "ExpandCollapsePanelStylePlusMinus" is the Template applied on Togglebutton in the style. If there is a way to change the Togglebutton template in same style (on runtime) rather than changing the full style, then that can also work.
Any suggestion on error or alternate approach to change style on runtime (with triggers and DoubleAnimation) is much appreciated.