【问题标题】:Changing between named styles在命名样式之间进行更改
【发布时间】:2012-01-12 19:43:04
【问题描述】:

几个月前,在一个 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>

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

我找到了更改代码样式的示例,但我无法创建两个相同的样式。我给它 ax:name="transparentListbox",复制它,然后给另一个 x:name="normalListbox" 背景为蓝色,但我得到一个 XML 解析异常,它有两个样式元素,可能是因为它们都是一般尝试修改每个列表框。

我怎样才能让两个命名样式完成相同的事情(选择项目时修改背景),我可以根据需要在代码中切换?


编辑:

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

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

当模式改变时,以编程方式将命名样式分配给整个列表框是可以的。为每个 ListBoxItem 分配样式将涉及更新大量代码,因为该功能已展开。

也许解决方案是保持单一样式但将背景属性绑定到一个变量,如果这可能的话?

【问题讨论】:

    标签: wpf styles


    【解决方案1】:

    我一直在我的 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)
    

    【讨论】:

    • 我添加了一个键“StandardListboxItem”,将这两种样式移动到我的窗口资源而不是应用程序的资源中,然后使用这一行:lstPanels.Style = (Style) FindResource("StandardListboxItem");它抛出一个 XMLParse 异常,并以此作为内部异常: {"'ListBoxItem' TargetType 与元素 'ListBox' 的类型不匹配。"} 有什么想法吗?
    • 您将样式应用于 ListBox 而不是 ListBoxItem。您可能需要遍历您的项目并应用样式更改。
    • 这开始有点麻烦了。当应用程序更改模式时,在单个点将样式应用于列表框是一回事,但管理每个项目的单独样式有点麻烦。
    • 试试ItemContainerStyle,它应该设置ListBoxItem的样式
    【解决方案2】:

    我不会尝试修改代码中的样式。这可能是可行的,甚至可行,但这对我来说似乎是一个痛苦的世界。一个可能有帮助的想法是您可以从 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>
    

    一般来说,我个人尽量避免在代码中处理布局和视觉风格方面的考虑。

    【讨论】:

    • 我用有关用例的更多信息修改了我的问题。我要添加到列表框中的是从 UserPanel 派生的类,所以我看不到任何方法可以制作派生的 ListBoxItem。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-24
      • 2012-04-07
      • 1970-01-01
      • 2019-03-28
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多