2017-08-02 49 views
4

我正在寻找修改WPF ListView,以便项目水平呈现,并且第一个项目和所有后续项目之间有一个分隔符。像这样:Horizontal list with first item separated如何覆盖ListView的ContentTemplate以添加垂直分隔符?

我已经得到了水平位,但我坚持使用分隔符。我尝试使用DataTemplate,但这将分隔符合并到实际项目中,这意味着当我悬停时它会突出显示(注意我使用Caliburn,但我不认为它会影响很多问题):

<UserControl.Resources> 
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
</UserControl.Resources> 
<StackPanel Margin="20"> 
    <ListView Name="Items" BorderThickness="0"> 
     <ListView.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <ContentControl cal:View.Model="{Binding}" /> 
        <Border Name="Separator" Width="2" Margin="5,10" HorizontalAlignment="Center" Background="Red" Visibility="{Binding IsFirst, Converter={StaticResource BooleanToVisibilityConverter}}" /> 
       </StackPanel> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
     <ListView.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel Orientation="Horizontal" /> 
      </ItemsPanelTemplate> 
     </ListView.ItemsPanel> 
    </ListView> 
</StackPanel> 

的项目是这个边界非常基本的观点:

<Border Background="White" BorderBrush="Black" BorderThickness="2"> 

如何,它看起来与的DataTemplate:

Incorrectly highlighting the selector

spendi后纳克早上模板上读了,我决定一个控件模板是其经过斗争给了我这个代码的解决方案:

<UserControl.Resources> 
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
    <Style TargetType="ListViewItem"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="ListViewItem"> 
        <StackPanel Margin="10" Orientation="Horizontal"> 
         <ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" /> 
         <Border Name="Separator" Width="2" Margin="5,10" HorizontalAlignment="Center" Background="Red" Visibility="{Binding IsFirst, Converter={StaticResource BooleanToVisibilityConverter}}" /> 
        </StackPanel> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</UserControl.Resources> 
<StackPanel> 
    <ListView Name="Items"> 
     <ListView.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel Orientation="Horizontal" /> 
      </ItemsPanelTemplate> 
     </ListView.ItemsPanel> 
    </ListView> 
</StackPanel> 

这看起来几乎是相同的,但现在我不能强调出于某种原因项目。我想也许我也重写了触发器,并尝试添加基于此答案的ControlTemplate.Triggers条目:Change selection-color of WPF ListViewItem,以突出显示行为,但没有成功。

我如何获得我正在查找的结果,并且ControlTemplate是进行此更改的正确位置?

编辑:理想情况下,我正在寻找一个解决方案,只使用xaml。

+1

该分隔符相对于“ListViewItem”本身而言不是容器的一部分。您现在正在使用水平“StackPanel”,试着编写自己的'Horizo​​ntalPanelWithSeparator'。 – Sinatr

+0

我会放弃它,谢谢。 – Jamey

回答

2

下面是自定义面板的快速尝试与分离

public class MyPanel : StackPanel 
{ 
    static MyPanel() 
    { 
     OrientationProperty.OverrideMetadata(typeof(MyPanel), new FrameworkPropertyMetadata(Orientation.Horizontal)); 
    } 

    protected override void OnRender(DrawingContext dc) 
    { 
     base.OnRender(dc); 
     if (Children.Count >= 2) 
     { 
      var child = Children[0] as FrameworkElement; 
      if (child != null) 
       dc.DrawLine(new Pen(Brushes.Red, 2), new Point(child.ActualWidth + 2, 5), new Point(child.ActualWidth + 2, ActualHeight - 5)); 
     } 
    } 
} 

使用这样

<ListView.ItemsPanel> 
    <ItemsPanelTemplate> 
     <local:MyPanel/> 
    </ItemsPanelTemplate> 
</ListView.ItemsPanel> 

目前面板不安排/测量孩子要分配给分隔空间,你将有以确保它们之间存在差距。

+0

感谢你们,我利用一点点的边缘摆弄手段,就能够产生我想要的行为。理想情况下,我正在寻找一种仅适用于xaml的解决方案,因此我将打开问题并继续试验,但如果没有其他问题出现,我会接受此解决方案。 – Jamey

0

使用ItemTemplateSelector来实现这一点。

如果您可以展示您的视图模型,我可以更具体地帮助您。但是第一个项目的数据模板与其他项目不同,并包含您想要的分隔符。其余的项目可以使用正常的模板。

作为替代方案,将可见性属性数据绑定到视图模型中的布尔字段,该属性仅适用于第一项。

+0

嗨Tanveer,谢谢你的回答,不幸的是能见度不是我的问题。当我将鼠标悬停在第一项上时(我可以在第二张图中看到),我很难让分隔符不包含在高亮框中。至于ViewModels,ItemViewModel只具有一个布尔IsFirst属性,ItemsViewModel只包含一个List 属性,我在构造函数中初始化了3个项目(传递给第一个和false到第二个)。 – Jamey

0

我设法弄清楚如何重新添加触发器(我确认使用我最喜欢的WPF工具WPF Inspector缺失)。一旦已完成的最后一个问题是,隔膜还触发一个鼠标事件我固定通过靶向内边界的第一个元素:

<UserControl.Resources> 
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
    <Style TargetType="ListViewItem"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="ListViewItem"> 
        <StackPanel Orientation="Horizontal"> 
         <Border x:Name="ItemBorder" Padding="2"> 
          <StackPanel> 
           <ContentPresenter /> 
          </StackPanel> 
         </Border> 
         <Border Name="Separator" Width="2" Margin="5,10" HorizontalAlignment="Center" Background="Red" Visibility="{Binding IsFirst, Converter={StaticResource BooleanToVisibilityConverter}}" /> 
        </StackPanel> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsSelected" Value="True"> 
          <Setter TargetName="ItemBorder" Property="Border.Background" Value="Blue" /> 
          <Setter TargetName="ItemBorder" Property="Border.BorderBrush" Value="Green" /> 
         </Trigger> 
         <DataTrigger Binding="{Binding ElementName=ItemBorder, Path=IsMouseOver}" Value="True"> 
          <Setter TargetName="ItemBorder" Property="Border.Background" Value="Yellow" /> 
         </DataTrigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</UserControl.Resources> 
<StackPanel> 
    <ListView Name="Items"> 
     <ListView.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel Orientation="Horizontal" /> 
      </ItemsPanelTemplate> 
     </ListView.ItemsPanel> 
    </ListView> 
</StackPanel> 

对于一些未知的原因的ItemBorder元件需要的2的填充否则无法看到边界。