在命名样式之间切换

时间:2011-12-04 22:16:31

标签: wpf styles

几个月前,在C#应用程序中,我开始使用ListBox作为某些UserPanel的容器。选择面板后,它会突出显示,就像任何列表框项一样。我找到了以下我能够添加的XAML,以便为所有项目提供透明背景(不确定我最初在哪里找到它或者我将它链接起来)

<Application.Resources>
    <Style TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border x:Name="border" Background="Transparent">
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter TargetName="border" Property="Background">
                                <Setter.Value>Transparent</Setter.Value>
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Application.Resources>

这很好但现在我需要有一个背景颜色而不是透明背景。只有一个列表框,内容发生了变化,所以我想以编程方式改变代码隐藏中的样式。

我找到了关于在代码中更改样式的示例,但我无法创建两个相同的样式。我把它给了ax:name =“transparentListbox”,复制了它,给了另一个x:name =“normalListbox”,背景为Blue,但我得到一个XML解析异常有两个样式元素,可能是因为它们都是通常会尝试修改每个列表框。

如何根据需要在代码之间切换,可以使用两个命名样式来完成同样的事情(在选择项目时修改背景)?


编辑:

在每种情况下,我的列表框都用于存储UserPanel。我使用lstPanels.Items.Add(p)将它们添加到列表框中,其中p是从UserPanel派生的类的实例。

当我第一次制作应用程序时,有多个窗口,因此需要透明度的窗口具有此样式,而那些需要选择项目的窗口则没有。管理多个窗口变得很麻烦,因此它被重新计算到一个窗口中,当模式改变时,列表框将被清除并加载不同类型的面板。有些人仍然需要透明背景,但现在有些人没有。

在模式更改时,以编程方式将命名样式作为整体分配给列表框,这样就可以了。为每个ListBoxItem分配样式将涉及对该功能展开的大量代码的更新。

也许解决方案是维护单一样式,但是如果可能的话,将background属性绑定到变量?

3 个答案:

答案 0 :(得分:2)

我总是在UserControl.Resources部分创建样式。

在你的情况下:

<Style x:Key="ListBoxStyle1" TargetType="MyDerivedListBoxItem">

...

<Style x:Key="ListBoxStyle2" TargetType="MyDerivedListBoxItem">

...

在后面的代码中,我以这种方式设置了样式。

If Not MyListBox.ItemContainerStyle.Equals(CType(Resources("ListBoxStyle1"), Style)) Then
                    MyListBox.ItemContainerStyle= CType(Resources("ListBoxStyle1"), Style)

答案 1 :(得分:1)

我不会试图修改代码中的样式。它可能是可行的,甚至是可行的,但这对我来说似乎是一个痛苦的世界。一个可能有用的想法是你可以从ListBoxItem继承,定义你自己的控件。然后,您可以在该继承器上放置一个依赖属性,如类型为bool的UseAlternateBackgroundColor或其他东西。

然后,你会修改你的风格:

<Style TargetType="MyDerivedListBoxItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type MyDerivedListBoxItem}">
                <Border x:Name="border" Background="Transparent">
                    <ContentPresenter />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter TargetName="border" Property="Background">
                            <Setter.Value>Transparent</Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="UseAlternateBackgroundColor" Value="true">
                        <Setter TargetName="border" Property="Background">
                            <Setter.Value>Black</Setter.Value>
                        </Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

一般来说,我个人尽量避免在代码中尽可能地处理布局和视觉风格问题。

答案 2 :(得分:1)

你需要设置不同的x:Key指令,如果样式是资源,Name无论如何都是无用的。如果您未设置密钥,则TargetType将用作密钥,而不会导致冲突。要在代码中应用其中一种样式,您可以使用相应的键调用FindResource