2016-10-24 5 views
0

У меня есть ItemsControl с привязываемыми источниками элементов и настраиваемым datetemplate для каждого элемента. Элементы разделяются линией. Но последний элемент также имеет разделитель, и это моя проблема, как не отображать строку для последнего элемента. Я нашел решение, но оно работает в WPF:Разделитель строк в DataTemplate для ListView

How can a separator be added between items in an ItemsControl

EDIT: Вот мой шаблон:

<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> 

ответ

0

Может, лучше поставить Seperator на вершине, потому что будет легче обнаружить, а не знать последний элемент. Положив его на вершину, вы получите 1 строку для первого элемента, чтобы разрешить это, добавьте привязку к свойству видимости разделителя, используя конвертер. Вы передаете индекс предмета, и если индекс элемента 1 скрывает разделителя, в противном случае покажите его.

Чтобы получить индекс элемента, рассмотрим пример здесь: http://www.bendewey.com/index.php/523/alternating-row-color-in-windows-store-listview

+0

Это хорошее решение. Но ItemsControl не имеет свойства индекса – JuP

+0

Вы говорите о ListView? В методе PrepareContainerForItemOverride вам просто нужно вызвать метод IndexFromContainer, чтобы получить индекс для текущего элемента ... если он не является ListView, добавьте некоторый код/​​xaml, чтобы мы могли видеть и не предполагать .... – Depechie

+0

I ' m talk about ItemsControl – JuP

0

Там, наверное, несколько способов сделать это, вот мое взятие.

Стиль пункт контейнеры вашего 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), если вы хотите его повторно использовать.
  • Он будет поддерживать правильный внешний вид, даже если элементы добавляются/удаляются из списка или когда элементы переупорядочиваются.
  • Он корректно работает с виртуализацией пользовательского интерфейса.
  • Он не зависит от данных, связанных с видом списка.

Screenshot


EDIT

Похоже, вы имели в виду для ItemsControl, а не ListView. Если это так, то вам придется что-то сделать по ответу Депечи, потому что ItemsControl не имеет события ContainerContentChanging (подкласс ItemsControl и переопределяет PrepareContainerForItemOverride), но это вряд ли будет работать для динамических списков с добавленными и удаленными элементами во время выполнения. Вы должны экспериментировать с различными решениями, если это важно для вас.

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; 
    } 

Что вы думаете?

Смежные вопросы