Continue to change WPF grid

Is it possible to continue the change styles in the form of a grid, even if there are no elements?

alt text

As you can see, after the last element, the template stops.

+3
source share
1 answer

Yes, WPF provides a pretty elegant way to implement this, because its template engine allows you to fill in an unused area GridViewwith whatever you like.

All you have to do is change the template ListViewto draw an unused section with VisualBrush, which usually consists of two GridViewItemsvertically stacked (in general it will be AlternationCount GridViewItems).

- , ScrollViewer. Items.Count AlternationCount. , Control, , ListView. "ContinueAlternation".

ListView, local:ContinueAlternation, ScrollViewer, DockPanel, :

<ControlTemplate TargetType="{x:Type ListView}">
  <Border BorderThickness="{TemplateBinding BorderThickness}"
          BorderBrush="{TemplateBinding BorderBrush}"
          Background="{TemplateBinding Background}"
          SnapsToDevicePixels="True">
    <DockPanel>
      <ScrollViewer DockPanel.Dock="Top"
                    Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}"
                    Padding="{TemplateBinding Padding}">
        <ItemsPresenter SnapsToDevicePixels="True" />
      </ScrollViewer>

      <local:ContinueAlternation
        ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
        AlternationCount="{TemplateBinding AlternationCount}"
        ItemsCount="{Binding Items.Count,
                          RelativeSource={RelativeSource TemplatedParent}}" />

    </DockPanel>
  </Border>
</ControlTemplate>

ContinueAlternation Rectangle, tiled VisualBrush, ItemsControl, , :

<ControlTemplate TargetType="{x:Type local:ContinueAlternation}">
  <Rectangle>
    <Rectangle.Fill>

      <VisualBrush TileMode="Tile" Stretch="None"
                   ViewPortUnits="Absolute"
                   ViewPort="{TemplateBinding ViewportSize}">

        <ItemsControl x:Name="PART_ItemsControl"
                      ItemsSource="{Binding}" />
      </VisualBrush>
    </Rectangle.Fill>
  </Rectangle>
</ControlTemplate>

DataContext ListViewItem, AlternationCount ItemsCount:

public class ContinueAlternation
{
  public Style ItemsContainerStyle ... // Declare as DependencyProperty using propdp snippet
  public int AlternationCount ... // Declare as DependencyProperty using propdp snippet
  public int ItemsCount ... // Declare as DependencyProperty using propdp snippet

  protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
  {
    if(e.Property==ItemsContainerStyleProperty ||
       e.Property==AlternationCountProperty ||
       e.Property==ItemsCountProperty)
    {
      // Here is where we build the items for display
      DataContext =
        from index in Enumerable.Range(ItemsCount,
                                       ItemsCount + AlternationCount)
        select BuildItem( index % AlternationCount);
    }
  }
  ListViewItem BuildItem(int alternationIndex)
  {
    var item = new ListViewItem { Style = ItemsContainerStyle };
    ItemsControl.SetAlternationIndex(item, alternationIndex);
    return item;
  }

  protected override Size MeasureOverride(Size desiredSize)
  {
    var ic = (ItemsControl)GetTemplateChild("PART_ItemsControl");
    ic.Width = desiredSize.Width;
    Size result = base.MeasureOverride(desiredSize);
    ViewportSize = new Size(ic.DesiredSize);
    return result;
  }
  public Size ViewportSize ... // Declare as DependencyProperty using propdp snippet
}

, PropertyChangedCallback OnPropertyChanged.

-, , - . - MinHeight Content ItemsContainerStyle. ContinueAlternation , ListViewItem.

, , , .

+2

Source: https://habr.com/ru/post/1736820/


All Articles