ListView

时间:2016-10-24 07:28:28

标签: xaml windows-runtime uwp winrt-xaml uwp-xaml

我有ItemsControl,每个项目都有可绑定的itemsource和自定义的datetemplate。项目按行分隔。但是最后一项也有分隔符,这是我的问题,如何不为最后一项渲染线。我找到了这个解决方案,但它在WPF中工作:

How can a separator be added between items in an ItemsControl

修改 这是我的模板:

<ItemsControl Grid.Row="1"  ItemsSource="{x:Bind ViewModel.AvailableStatuses}" x:Name="Statuses">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Vertical" Padding="60,0,60,12"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid Background="Transparent">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>
                                <i:Interaction.Behaviors>
                                    <core:EventTriggerBehavior EventName="Tapped">
                                        <core:InvokeCommandAction Command="{Binding ElementName=ContentGrid, Path=DataContext.ChangeStatusCommand}" CommandParameter="{Binding}"/>
                                    </core:EventTriggerBehavior>
                                </i:Interaction.Behaviors>
                                <Rectangle StrokeThickness="0.4" Height="0.4" x:Name="Separator" 
                                   VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Stroke="#D1D3D4" />
                                <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Stretch">
                                    <Image Source="{Binding Converter={StaticResource SelectContactStatusConverter}}" Margin="0,8,12,8"/>
                                    <TextBlock Text="{Binding Converter={StaticResource EnumContactStatusToTextConverter}}" FontSize="20" VerticalAlignment="Center" Foreground="Black"/>
                                </StackPanel>
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>

4 个答案:

答案 0 :(得分:1)

这可能有几种不同的方法,这是我的看法。

使用边框画笔和厚度设置ListView的项容器样式,并订阅ContainerContentChanging事件:

<ListView ContainerContentChanging="ListView_ContainerContentChanging">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="BorderThickness" Value="0,1,0,0"/>
        </Style>
    </ListView.ItemContainerStyle>

    <x:String>1</x:String>
    <x:String>2</x:String>
    <x:String>3</x:String>
    <x:String>4</x:String>
</ListView>

在你的代码背后:

private void ListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
    if (args.InRecycleQueue)
    {
        // Item is being recycled, make sure first item has no border
        if (args.ItemIndex == 0)
        {
            var first = (ListViewItem)sender.ContainerFromIndex(0);
            if (first != null)
            {
                first.BorderThickness = new Thickness(0);
            }
        }
    }
    else if (args.ItemIndex == 0)
    {
        // A new first item
        ((ListViewItem)args.ItemContainer).BorderThickness = new Thickness(0);

        var second = (ListViewItem)sender.ContainerFromIndex(1);
        if (second != null)
        {
            second.ClearValue(BorderThicknessProperty);
        }
    }
    else
    {
        // A new internal item
        ((ListViewItem)args.ItemContainer).ClearValue(BorderThicknessProperty);
    }
}

我决定使用这种方法有几个原因:

  • 将边框样式应用于ListViewItem而不是ItemTemplate是有意义的,因为无论哪个项目模板用于特定项目,它对列表中的所有项目都是相同的。此外,它还将确保该线条触及ListView的左右边缘。
  • 可以在XAML中调整分隔符的视觉外观。如果要重用它,可以将代码隐藏放入行为(或ListView的子类)。
  • 即使在列表中添加/删除项目或重新排序项目时,它也会保持正确的外观。
  • 它可以正常使用UI虚拟化。
  • 它独立于绑定到列表视图的数据。

Screenshot

修改

看起来你的意思是ItemsControl,而不是ListView。如果是这种情况,那么你必须在Depechie的答案中做一些事情,因为ItemsControl没有ContainerContentChanging事件(子类ItemsControl而是覆盖PrepareContainerForItemOverride),但这可能不适用于添加和删除项目的动态列表运行。如果这对您很重要,您必须尝试不同的解决方案。

答案 1 :(得分:0)

将分离器放在最顶层可能会更好,因为这样更容易检测,而不是知道最后一个元素。 将其置于顶部将导致第一项的1行到多,为了解决此问题,使用转换器在分离器的可见性属性上添加绑定。 您传递项目索引,如果项目索引为1,则隐藏分隔符,否则显示它。

要获取项目的索引,请在此处查看示例:http://www.bendewey.com/index.php/523/alternating-row-color-in-windows-store-listview

答案 2 :(得分:0)

我用这种方式解决了我的问题:

private void Statuses_OnLoaded(object sender, RoutedEventArgs e)
    {
        var s = (ItemsControl) sender;
        var container = s.ContainerFromIndex(0);
        var element = container.FindChildren<Rectangle>("Separator");
        element.Visibility = Visibility.Collapsed;
    }

您怎么看?

答案 3 :(得分:0)

<ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            </Style>
        </ListView.ItemContainerStyle>