我有一个基于标准TreeView的自定义TreeListView - 具有以下样式:
<Style TargetType="{x:Type c:TreeListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type: c:TreeListView}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel>
<GridViewHeaderRowPresenter DockPanel.Dock="Top" Columns="{Binding Path=Columns, RelativeSource={RelativeSource TemplatedParent}}" />
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
因为我没有ScrollViewer,所以内容不会滚动,所以如果内容需要的空间比可用空间多,它看起来像这样:
所以我添加了一个ScrollViewer,以便样式现在看起来像这样:
<Style TargetType="{x:Type c:TreeListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type: c:TreeListView}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Focusable="False" Padding="{TemplateBinding Padding">
<DockPanel>
<GridViewHeaderRowPresenter DockPanel.Dock="Top" Columns="{Binding Path=Columns, RelativeSource={RelativeSource TemplatedParent}}" />
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</DockPanel>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
随着内容在第一张图片中展开,内容无法滚动,但列标题也会出现问题,这是不希望的:D
有人可以帮助我,以便只滚动内容,而不是绑定到 GridViewHeaderRowPresenter 的列吗?
谢谢!
[编辑]
感谢右边的相关链接,我找到了答案here。
而不是 ScrollViewer 中的 DockPanel ,我只需要在 ScrollViewer 中包含 ItemsPresenter 。所以使用以下 Style 它现在可以使用。
<Style TargetType="{x:Type c:TreeListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:TreeListView}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel>
<GridViewHeaderRowPresenter DockPanel.Dock="Top" Columns="{Binding Path=Columns, RelativeSource={RelativeSource TemplatedParent}}" />
<ScrollViewer Focusable="False" Padding="{TemplateBinding Padding}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
非常感谢Nikhil Agrawal的代码!
答案 0 :(得分:0)
给出的解决方案是不完整的,只有在你有一个固定的宽度控制时才会起作用。仅包装ItemsPresenter
标题列将不会在需要时水平滚动。这会导致值列移位,然后标题不匹配。
我已尝试将SelectiveScrollingGrid.SelectiveScrollingOrientation="Horizontal"
应用于GridViewHeaderRowPresenter
但尚未成功使用该方法。
相反,您可以向GridViewHeaderRowPresenter
和ItemsPresenter
添加滚动查看器,然后将它们同步。它不是最好的解决方案,但至少它可行。
<Style TargetType="{x:Type local:TreeListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TreeListView}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel>
<ScrollViewer DockPanel.Dock="Top"
HorizontalScrollBarVisibility="Hidden"
Name="scrollViewerHeader"
VerticalScrollBarVisibility="Disabled">
<GridViewHeaderRowPresenter Columns="{StaticResource gvcc}"/>
</ScrollViewer>
<ScrollViewer HorizontalScrollBarVisibility="Auto"
Name="scrollViewerBody"
VerticalScrollBarVisibility="Auto">
<ItemsPresenter />
</ScrollViewer>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
背后的代码:
public class TreeListView : TreeView
{
private ScrollViewer _scrollViewerHeader;
private ScrollViewer _scrollViewerBody;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_scrollViewerHeader = (ScrollViewer)Template.FindName("scrollViewerHeader", this);
_scrollViewerBody = (ScrollViewer)Template.FindName("scrollViewerBody", this);
_scrollViewerBody.ScrollChanged += (sender, e) =>
{
_scrollViewerHeader.Width = e.ViewportWidth;
_scrollViewerHeader.ScrollToHorizontalOffset(e.HorizontalOffset);
};
}
}
答案 1 :(得分:0)
DataGrid
解决问题的方法是自定义ScrollViewer
的模板,将GridViewHeaderRowPresenter
放在ScrollViewer
ScrollContentPresenter
之外:
这样,当滚动条滚动时,它们不会影响标题行。
使用ListView
的{{1}}在这里做类似的事情:
https://github.com/dotnet/wpf/blob/059ba38771aef10d2172a3ca0e247dfbfa8cefde/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Aero2/Themes/Aero2.NormalColor.xaml#L2628
同时,他们将标题行包装在另一个GridView
中,老实说,我不明白为什么。
一旦我发现更多信息,我将继续回答这个问题。我认为这种方法比同步滚动查看器更干净。