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

时间:2014-06-12 08:48:12

标签: c# wpf wpf-style

我在XAML中定义了标签控件和样式:

<Style x:Key="EditModeEditedHiddenTemplate" TargetType="Control">
   <Setter Property="Background" Value="DarkOrange" />
   <Setter Property="Visibility" Value="Visible" />
</Style>

......其他的东西......

<Label Grid.Column="0" Grid.Row="1" Name="SomeName" Visibility="Hidden">Some content</Label>

然后,在基于用户输入的代码后面,我将样式应用于控件,如下所示:

var editModelControlStyle = new Style(control.GetType());

foreach (var setter in editModeStyleTemplate.Setters)
{
    editModelControlStyle.Setters.Add(setter);
}

editModelControlStyle.BasedOn = control.Style;

control.Style = editModelControlStyle;

使用大多数依赖项属性,这可以正常工作,例如Background。但是,这在可见性方面不起作用,控制仍然是不可见的。

你能帮助我理解为什么会这样以及如何解决它吗?

1 个答案:

答案 0 :(得分:3)

如果您将Visibility属性设置为内联如下:

<Label Name="SomeName" Visibility="Hidden" Content="Something" />

...那么这意味着此指定值将覆盖已应用Style中设置的任何值。

<Style x:Key="EditModeEditedHiddenTemplate" TargetType="Control">
   <Setter Property="Background" Value="DarkOrange" />
   <Setter Property="Visibility" Value="Visible" /><!-- No effect-->
</Style>

DependencyProperty可以从许多不同的来源设置,例如Style s,Animation s和内联名称,但是因此,它们具有特定的顺序precedence,指定哪个源应覆盖其他源。您可以在MSDN上Dependency Property Value Precedence页面的“依赖关系属性设置优先级列表”部分找到更多相关信息。

从该列表中,您可以看到只有Animation和Property系统强制可以覆盖内联属性值。因此,如果您无法从XAML中删除Visibility="Hidden",则只能在动画中或通过属性强制将Visibility属性设置为Visible。但是,这些都需要更改XAML才能工作。您可以通过以下方式更改Visibility中的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>

我将Storyboard.BeginTime设置为1秒,以便您可以看到文本显示,但同样,这可以设置为0秒加载后立即发生。属性强制要求您将数据绑定到Visibility属性:

<Label Name="SomeName" Visibility="{Binding SomeProperty}" Content="Something" />

但是,如果您无法更改Label上的XAML,则无法单独在XAML中创建VisibilityVisible。它可以在代码中执行此操作...您只需要一些条件来触发更改。在此示例中,我刚刚向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;
}

但是,仍然需要更改XAML才能执行此操作。也许您可以在代码中附加处理程序?