简体   繁体   English

将Visibility.Visible应用于隐藏控件的样式不起作用。

[英]Applying style with Visibility.Visible to a hidden control doesn't work.

I have a label control and style defined in XAML: 我在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. 使用大多数依赖项属性,这可以正常工作,例如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: 如果您将Visibility属性设置为内联,如下所示:

<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设置的任何值。

<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. DependencyProperty可以从许多不同的源设置,例如Style s, Animation s和inline to name,但是因此,它们具有特定的优先顺序,它指定哪个源应该覆盖其他源。 You can find out more about this in the Dependency Property Setting Precedence List section of the Dependency Property Value Precedence page on MSDN. 您可以在MSDN上的“ 依赖项属性值优先级”页面的“依赖项属性设置优先级列表”部分中找到有关此内容的更多信息。

From that list, you can see that only Animation s and Property system coercion can override an inline property value. 从该列表中,您可以看到只有Animation和属性系统强制可以覆盖内联属性值。 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. 因此,如果您无法从XAML中删除Visibility="Hidden" ,则只能在动画中或通过属性强制将Visibility属性设置为Visible However, these would both require a change to the XAML in order to work. 但是,这些都需要更改XAML才能工作。 This is how you could change the Visibility value in an Animation : 这是您可以更改AnimationVisibility值的方法:

<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. 我将Storyboard.BeginTime设置为1秒,以便您可以看到文本显示,但同样,这可以设置为0秒加载后立即发生。 Property coercion would require that you data bind a property to the Visibility property: 属性强制要求您将数据绑定到Visibility属性:

<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. 但是,如果无法更改Label上的XAML,则无法单独在XAML中使VisibilityVisible 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添加了一个单击处理程序,以获取对后面代码的访问:

<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. 但是,您仍然需要更改XAML才能执行此操作。 Perhaps you could attach a handler in code instead? 也许您可以在代码中附加处理程序?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM