为ListBoxItem模板应用现有样式



我正试图为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>

我觉得我错过了一些简单的东西。。。有人能帮我发现吗?

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属性,该属性完全不相关,在UI中显示毫无意义,而且您无论如何都无法控制它。

数据不属于ControlTemplates,仅属于DataTemplates。

更改您的模板如下:

                <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指定为ListBox:的ItemTemplate

<ListBox ...>
   <ListBox.ItemTemplate>
      <DataTemplate>
          <!-- ... -->
      </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

为什么Image.Source与类型为double的属性绑定?这毫无意义。要么在那里放一个特定的资源:

<Image Source="/resources/somepic.png"/>

如果你想根据某些数据动态更改图像,那么它属于DataTemplate,而不是ControlTemplate

-------------------------------------------------------------------------------------------

我建议你阅读以下材料:

  • MSDN:WPF内容模型
  • MSDN:WPF控制内容模型
  • Dr。WPF:项目控件A到Z

相关内容

  • 没有找到相关文章

最新更新