Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何覆盖ListView的ContentTemplate以添加垂直分隔符?_C#_Wpf_Listview_Controltemplate - Fatal编程技术网

C# 如何覆盖ListView的ContentTemplate以添加垂直分隔符?

C# 如何覆盖ListView的ContentTemplate以添加垂直分隔符?,c#,wpf,listview,controltemplate,C#,Wpf,Listview,Controltemplate,我希望修改WPF列表视图,以便水平呈现项目,并且在第一个项目和所有后续项目之间有一个分隔符。大概是这样的: 我有水平钻头,但我被分离器卡住了。我尝试使用DataTemplate,但它将分隔符合并到实际项目中,这意味着当我悬停时它会突出显示(注意,我使用的是Caliburn,但我认为它不会对问题产生太大影响): 这些项目是具有此边框的非常基本的视图: <Border Background="White" BorderBrush="Black" BorderThickness="2">

我希望修改WPF列表视图,以便水平呈现项目,并且在第一个项目和所有后续项目之间有一个分隔符。大概是这样的:

我有水平钻头,但我被分离器卡住了。我尝试使用DataTemplate,但它将分隔符合并到实际项目中,这意味着当我悬停时它会突出显示(注意,我使用的是Caliburn,但我认为它不会对问题产生太大影响):


这些项目是具有此边框的非常基本的视图:

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

DataTemplate的外观:

在花了一上午的时间阅读模板之后,我决定使用ControlTemplate作为解决方案,经过一番努力,我得到了以下代码:

<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条目,该条目基于以下答案:恢复突出显示行为,但没有成功

我怎样才能得到我想要的结果,ControlTemplate是否是进行此更改的正确位置

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

使用它来实现这一点

如果你能展示你的视图模型,我可以具体地帮助你。但是第一个项目的数据模板将不同于其他项目,并且包含所需的分隔符。其余项目可以使用普通模板


另一种方法是,将可见性属性数据绑定到视图模型中的布尔字段,该字段仅适用于第一项。

下面是使用分隔符自定义面板的快速尝试

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>


目前面板没有安排/测量子项来为分隔符分配空间,您必须确保它们之间有一个余量。

我设法找到了如何重新添加触发器(我使用我最喜欢的新WPF工具确认缺少触发器)。完成后,最后一个问题是分隔符还触发了第一个元素的鼠标悬停事件,我通过瞄准内边框修复了该事件:

<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,否则无法看到边框。

该分隔符是项目容器的一部分,而不是
ListViewItem
本身。您正在使用水平
StackPanel
现在,请尝试使用Separator编写自己的
水平面板
。我会尝试一下,谢谢。嗨,Tanveer,谢谢您的回答,不幸的是,可见性不是我的问题。当我将鼠标悬停在第一项上时,我正在努力使分隔符不包含在突出显示框中(如第二张图片所示)。至于ViewModels,
ItemViewModel
只是有一个
boolean IsFirst
属性,而
ItemsViewModel
只是包含一个
List
属性,我在构造函数中用3个项初始化它(将true传递给第一个项,将false传递给第二个项),只要稍微调整一下利润,我就能做出我想要的行为。理想情况下,我正在寻找一个只有xaml的解决方案,所以我会把这个问题留着,继续试验,但如果没有其他问题,我会接受这个。
<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>