2

我在 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;

对于大多数依赖属性,这可以正常工作,例如背景。但是,这在可见性方面不起作用,控件仍然是不可见的。

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

4

1 回答 1

4

如果您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>

DependencyPropertys 可以从许多不同的源中设置,例如Styles、Animations 和 inline 等等,因此,它们具有特定的优先顺序,指定哪个源应该覆盖其他源。您可以在 MSDN 上的Dependency Property Value Precedence页面的 Dependency Property Setting Precedence List 部分中找到有关此内容的更多信息。

从该列表中,您可以看到只有Animations 和 Property system coercion 可以覆盖内联属性值。因此,如果您无法Visibility="Hidden"从 XAML 中删除 ,则只能在动画中或通过属性强制将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" />

但是,如果您无法更改 上的 XAML Label,那么您无法单独在 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 才能做到这一点。也许您可以在代码中附加一个处理程序?

于 2014-06-12T09:23:14.440 回答