我正在尝试为ListBox
中的项目添加样式,我之前为ListViewItem创建了这种样式,它关于TextBlock,Image和Border,当项目事件引发时它会改变颜色( IsSelected ,IsMouseOver,IsSelectionActive ),现在我想保留这种风格并将其应用于添加到ListBox
的任何项目
<Style x:Key="ListBoxPCInfoStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="2,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid HorizontalAlignment="Left" Height="74" VerticalAlignment="Top" Width="68">
<Image x:Name="Img" Width="56" Height="56" Margin="6,0,6,18" Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path= ActualHeight}"/>
<Border x:Name="border" BorderBrush="{x:Null}" BorderThickness="1" HorizontalAlignment="Left" Height="74" VerticalAlignment="Top" Width="68" CornerRadius="2.5"/>
<TextBlock HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="{TemplateBinding Name}" VerticalAlignment="Bottom" Width="Auto" Height="17" TextAlignment="Center" Margin="4,0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="border">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#33C1DEFF" Offset="0"/>
<GradientStop Color="#41A5CDFF" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" TargetName="border" Value="#FF7DA2CE"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF7DA2CE"/>
<Setter Property="Background" TargetName="border">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#97C1DEFF" Offset="0"/>
<GradientStop Color="#A7A5CDFF" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="Selector.IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" TargetName="border" Value="#FFB4B4B4"/>
<Setter Property="Background" TargetName="border">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#7FE5E5E5" Offset="0"/>
<GradientStop Color="#B2CCCCCC" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我有这个ListBox
<ListBox x:Name="ListHosts" Background="{x:Null}" BorderBrush="{x:Null}">
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border x:Name="border" BorderBrush="{x:Null}" BorderThickness="1" HorizontalAlignment="Left" Height="20" VerticalAlignment="Top" Width="50" CornerRadius="2.5"/>
<Image x:Name="Img" Source="BtnImg/Computer.png" Stretch="None" Margin="3,0,10,0"/>
<TextBlock x:Name="PCName" Margin="0,7" TextWrapping="Wrap" Height="16" HorizontalAlignment="Left"><Run Text="{Binding Name}"/></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox>
我觉得我在这里缺少一些简单的东西......有人能帮助我发现它吗?
答案 0 :(得分:0)
2个选项:
从样式中删除x:Key
:
<Style TargetType="{x:Type ListBoxItem}">
<!-- ... -->
这将使样式适用于资源范围内的所有 ListBoxItem
。
或
明确引用ListBox
中的样式:
<ListBox ItemContainerStyle="{StaticResource ListBoxPCInfoStyle}">
<!-- ... -->
无论如何,你所有的XAML都错了。您正在定义ListBoxItem.Template
,如下所示:
<Grid HorizontalAlignment="Left" Height="74" VerticalAlignment="Top" Width="68">
<Image x:Name="Img" Width="56" Height="56" Margin="6,0,6,18" Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path= ActualHeight}"/>
<Border x:Name="border" BorderBrush="{x:Null}" BorderThickness="1" HorizontalAlignment="Left" Height="74" VerticalAlignment="Top" Width="68" CornerRadius="2.5"/>
<TextBlock HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="{TemplateBinding Name}" VerticalAlignment="Bottom" Width="Auto" Height="17" TextAlignment="Center" Margin="4,0"/>
</Grid>
这使得自定义DataTemplates
无法在任何地方引入。您需要在某处留下ContentPresenter
,以便WPF有机会将DataTemplated内容放在其中。
TextBlock
毫无意义。你绑定了ListBoxItem.Name
属性,这是完全无关紧要的,没有任何意义可以显示在用户界面中,无论如何都无法控制。
数据不属于ControlTemplate
s,仅属于DataTemplate
s。
更改模板,如下所示:
<Grid HorizontalAlignment="Left" Height="74" VerticalAlignment="Top" Width="68">
<Image x:Name="Img" Width="56" Height="56" Margin="6,0,6,18" Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path= ActualHeight}"/>
<Border x:Name="border" BorderBrush="{x:Null}" BorderThickness="1" HorizontalAlignment="Left" Height="74" VerticalAlignment="Top" Width="68" CornerRadius="2.5"/>
<ContentPresenter ContentSource="Content"/>
</Grid>
ListBox
XAML也错了:
通过这样做:
<ListBox ...>
<DataTemplate>
<!-- ... -->
</DataTemplate>
</ListBox>
您将DataTemplate
作为项目放在ListBox中,这不是您想要的。
您需要专门为DataTemplate
指定ItemTemplate
作为ListBox
:
<ListBox ...>
<ListBox.ItemTemplate>
<DataTemplate>
<!-- ... -->
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
为什么Image.Source
绑定到double
类型的属性?这是没有意义的。
要么在那里放一个特定的资源:
<Image Source="/resources/somepic.png"/>
或
如果您想动态更改依赖于某些数据的图片,那么该图片属于DataTemplate
,而不属于ControlTemplate
。
我建议你阅读以下资料: