我找到了一种仅在基于此解决方案的 gridview 底部添加滚动的方法:How can I create a group footer in a WPF ListView (GridView)。它看起来有点老套,但似乎还没有解决方案。我在 xaml 中所做的是将组描述绑定到一个假属性,以便仅显示一次页脚。
XAML:
<PropertyGroupDescription PropertyName="fake" />
然后我修改了一个页脚模板,让它显示一个滚动条:
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<DockPanel>
<Grid DockPanel.Dock="Bottom" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=first, Path=Width, UpdateSourceTrigger=PropertyChanged}" />
<ColumnDefinition Width="{Binding ElementName=second, Path=Width, UpdateSourceTrigger=PropertyChanged}" />
</Grid.ColumnDefinitions>
<ScrollBar Grid.Column="0" Orientation="Horizontal" Scroll="ScrollBar1_Scroll"
Width="{Binding ElementName=first, Path=Width, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" >
</ScrollBar>
<ScrollBar Grid.Column="1" Orientation="Horizontal" Scroll="ScrollBar2_Scroll"
Width="{Binding ElementName=second, Path=Width, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/>
</Grid>
<ItemsPresenter />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
调整带有列的滚动条的大小需要很多绑定。那里的另一个技巧:您必须最初Width
为每个设置,GridViewColumn
否则滚动条只有在您手动调整列大小后才会出现。我将单元格Margin
的内容移动StackPanel
到CellTemplate
. 下面是整个代码,我认为这不是一个完整的工作解决方案,但它是一个很好的起点。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid>
<Grid.Resources>
<CollectionViewSource x:Key="ViewSource" Source="{Binding Path=Collection, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window} }">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="fake" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Grid.Resources>
<HeaderedItemsControl Header="ListView">
<StackPanel>
<ListView ItemsSource="{Binding Source={StaticResource ViewSource}, UpdateSourceTrigger=PropertyChanged}" x:Name="Lv" Margin="5,5,5,5">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<DockPanel>
<Grid DockPanel.Dock="Bottom" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=first, Path=Width, UpdateSourceTrigger=PropertyChanged}" />
<ColumnDefinition Width="{Binding ElementName=second, Path=Width, UpdateSourceTrigger=PropertyChanged}" />
</Grid.ColumnDefinitions>
<ScrollBar Grid.Column="0" Orientation="Horizontal" Scroll="ScrollBar1_Scroll"
Width="{Binding ElementName=first, Path=Width, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" >
</ScrollBar>
<ScrollBar Grid.Column="1" Orientation="Horizontal" Scroll="ScrollBar2_Scroll"
Width="{Binding ElementName=second, Path=Width, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/>
</Grid>
<ItemsPresenter />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.View >
<GridView >
<GridViewColumn Header="Name" x:Name="first" Width="50">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Margin="{Binding Path=Offset1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window} }">
<TextBlock x:Name="tb1" Text="{Binding name}"></TextBlock>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Price" x:Name="second" Width="50">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Margin="{Binding Path=Offset2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window} }" >
<TextBlock Text="{Binding price}"></TextBlock>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</HeaderedItemsControl>
</Grid>
</Window>
和代码隐藏
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls.Primitives;
namespace WpfApplication1
{
public partial class MainWindow:INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
}
private List<MyItem> _collection = new List<MyItem>();
public List<MyItem> Collection
{
get { return _collection; }
set { _collection = value; InvokePropertyChanged(new PropertyChangedEventArgs("Collection")); }
}
private Thickness _offset1;
public Thickness Offset1
{
get { return _offset1; }
set { _offset1 = value; InvokePropertyChanged(new PropertyChangedEventArgs("Offset1")); }
}
private Thickness _offset2;
public Thickness Offset2
{
get { return _offset2; }
set { _offset2 = value; InvokePropertyChanged(new PropertyChangedEventArgs("Offset2")); }
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Collection.Add(new MyItem("item1", "10"));
Collection.Add(new MyItem("item2", "200"));
Collection.Add(new MyItem("item3", "600000"));
Collection.Add(new MyItem("item4", "1"));
}
private void ScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
//imitate scrolling here
double leftToRight = Offset1.Left;
if (e.ScrollEventType == ScrollEventType.SmallIncrement)
leftToRight += 5;
if (e.ScrollEventType == ScrollEventType.SmallDecrement)
leftToRight -= 5;
Offset1 = new Thickness(leftToRight, 0, 0, 0);
}
private void ScrollBar2_Scroll(object sender, ScrollEventArgs e)
{
//imitate scrolling here
double leftToRight = Offset2.Left;
if (e.ScrollEventType == ScrollEventType.SmallIncrement)
leftToRight += 5;
if (e.ScrollEventType == ScrollEventType.SmallDecrement)
leftToRight -= 5;
Offset2 = new Thickness(leftToRight, 0, 0, 0);
}
public event PropertyChangedEventHandler PropertyChanged;
public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, e);
}
}
public class MyItem
{
public string name { get; set; }
public string price { get; set; }
public MyItem(string n, string p)
{
name = n;
price = p;
}
}
}