几个月前,在一个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>
这工作得很好,但现在我有时需要有一个背景颜色,而不是透明的背景。只有一个列表框和内容的变化,所以我想以编程方式改变代码背后的风格。
我在代码中找到了改变风格的例子,但我无法创建两个相同风格的例子。我给了它一个x:name="transparentListbox",复制了它,并给了另一个x:name="normalListbox"与蓝色的背景,但我得到一个XML解析异常有两个样式元素,可能是因为他们都试图修改每个列表框。
我怎么能有两个命名的风格,完成相同的事情(修改背景时,一个项目被选中),我可以在代码之间切换需要?
编辑:
在任何情况下,我的列表框都用来存储userpanel。我使用lstpanel . items . add (p)将它们添加到列表框中,其中p是派生自UserPanel的类实例。
当我第一次制作应用程序时,有多个窗口,所以需要透明度的窗口有这种样式,而那些需要选择项目的窗口没有。管理多个窗口变得很麻烦,所以它被重新分解成一个窗口,当模式改变时,列表框将被清除并加载不同类型的面板。有些仍然需要透明背景,但现在有些不需要了。
当模式改变时,以编程方式为整个列表框指定命名样式是可以的。为每个ListBoxItem分配样式将涉及到大量代码的更新,因为该功能是分散的。
也许解决方案是保持单一的风格,但有背景属性绑定到一个变量,如果这是可能的?
我总是在UserControl中创建样式。参考资料部分。
在你的例子中:
<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)
我不会尝试修改代码中的样式。这可能是可行的,甚至是有效的,但这对我来说似乎是一个痛苦的世界。一个可能有用的想法是,您可以继承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>
一般来说,我个人尽量避免在代码中处理布局和视觉风格的考虑。
你需要设置不同的x:Key
指令,如果样式是资源,Name
是相当无用的。如果不设置密钥,则使用TargetType
作为密钥,会导致冲突。要在代码中应用其中一种样式,您可以使用相应的键调用FindResource
。