I have a label control and style defined in XAML:
<Style x:Key="EditModeEditedHiddenTemplate" TargetType="Control">
<Setter Property="Background" Value="DarkOrange" />
<Setter Property="Visibility" Value="Visible" />
</Style>
... other stuff ...
<Label Grid.Column="0" Grid.Row="1" Name="SomeName" Visibility="Hidden">Some content</Label>
Then, in code behind based on user input, i apply the style to the control like this:
var editModelControlStyle = new Style(control.GetType());
foreach (var setter in editModeStyleTemplate.Setters)
{
editModelControlStyle.Setters.Add(setter);
}
editModelControlStyle.BasedOn = control.Style;
control.Style = editModelControlStyle;
With most dependency properties this work fine, such as Background. However, this does not work when it comes to visibility, the control is still invisible.
Can you please help me understand why this is and how to solve it?
If you have set the Visibility
property inline like this:
<Label Name="SomeName" Visibility="Hidden" Content="Something" />
... then this will mean that this specified value will override any value that is set in an applied Style
.
<Style x:Key="EditModeEditedHiddenTemplate" TargetType="Control">
<Setter Property="Background" Value="DarkOrange" />
<Setter Property="Visibility" Value="Visible" /><!-- No effect-->
</Style>
DependencyProperty
s can be set from many different sources, such as Style
s, Animation
s and inline to name but a few, and as such, they have a particular order of precedence, which specifies which source should override other sources. You can find out more about this in the Dependency Property Setting Precedence List section of the Dependency Property Value Precedence page on MSDN.
From that list, you can see that only Animation
s and Property system coercion can override an inline property value. Therefore if you can't remove the Visibility="Hidden"
from the XAML, you can only set the Visibility
property to Visible
in an animation, or through property coercion. However, these would both require a change to the XAML in order to work. This is how you could change the Visibility
value in an Animation
:
<Label Name="SomeName" Visibility="Hidden" Content="Something">
<Label.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard BeginTime="0:0:1">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Label.Triggers>
</Label>
I set the Storyboard.BeginTime
to 1 second so that you could see the text appear, but equally, this could be set to 0 seconds to happen as soon as it is loaded. Property coercion would require that you data bind a property to the Visibility
property:
<Label Name="SomeName" Visibility="{Binding SomeProperty}" Content="Something" />
However, if you cannot change the XAML on the Label
, then you have no way to make the Visibility
value Visible
in XAML alone. It would be possible to do this in code though... you just need some condition in which to trigger the change. In this example, I have just added a click handler to the Grid
to gain access to the code behind:
<Grid PreviewMouseDown="OnPreviewMouseDown" Background="Transparent">
<Label Name="SomeName" Visibility="Hidden" Content="Something" />
</Grid>
...
private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
SomeName.Visibility = Visibility.Visible;
}
However, you would still need to change the XAML to do even this. Perhaps you could attach a handler in code instead?