有没有办法UIElement
从某种滚动效果中排除某些?我在列标题元素下方有一个网格元素。虽然我想在网格上完全滚动,但我希望标题只受水平滚动的影响。这样它在向下滚动时将始终保持在顶部。
这是我做的一个 mspaint 来解释,以防我的解释没有意义。
有没有办法UIElement
从某种滚动效果中排除某些?我在列标题元素下方有一个网格元素。虽然我想在网格上完全滚动,但我希望标题只受水平滚动的影响。这样它在向下滚动时将始终保持在顶部。
这是我做的一个 mspaint 来解释,以防我的解释没有意义。
为什么不将滚动查看器移动到绿色行内,然后为标题使用不同的滚动查看器。
然后将其全部包装在父容器中
所以喜欢
<Grid>
<HeaderControl>
<ScrollViewer />
</HeaderControl>
<BodyControl>
<ScrollViewer />
</BodyContent>
</Grid>
在一个滚动查看器中将它们包装在一起过于复杂。将其拆分为两个不同的滚动查看器将简化 IMO 问题。
如果您使用 2 个单独的滚动查看器会怎么样 - 一个包含标题和网格的外部滚动查看器,并且只处理水平滚动。
然后网格本身可以包装在一个单独的滚动查看器中,该查看器仅处理网格的垂直滚动。例如:
<ScrollViewer VerticalScrollBarVisibility="Disabled">
<!-- Header -->
<Grid>
</Grid>
<ScrollViewer HorizontalScrollBarVisibility="Hidden">
<!-- Content -->
<Grid>
</Grid>
<ScrollViewer />
</Grid>
虽然我不是 100% 确定这两种可见性设置 - 你可能需要玩弄它们才能看到什么有效
我只是想做同样的事情。我的解决方案是使用 Canvas 作为标题,使用 Scrollviewer 作为正文。
<Canvas>
<Grid Canvas.Left="{Binding ElementName=ValueScrollViewer, Path=HorizontalOffset, Converter={StaticResource DoubleMultiplyingConverter}, ConverterParameter=-1}">
Header
</Grid>
</Canvas>
<ScrollViewer Name="ValueScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
<Grid>
Table
</Grid>
</ScrollViewer>
带转换器:
public class DoubleMultiplyingConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var factor = System.Convert.ToDouble(parameter, CultureInfo.InvariantCulture);
var val = System.Convert.ToDouble(value);
return val * factor;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
要处理所有情况,您应该将静态部分(标题)和可滚动部分(正文)分开,并用ScrollViewer
. 这个解决方案在所有方面都是完美的,除了你的控件比屏幕(或外部控件)宽的情况,所以也应该允许水平滚动并且标题也应该滚动。你不能只使用内部滚动浏览器,因为垂直滚动条只有在水平滚动位于右边缘时才可见。
您不能仅从垂直滚动中排除标题,但您可以模拟水平滚动。你可以通过翻译转换来做到这一点。
<Grid>
<!-- body part. place it first to make it go to the background -->
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" x:Name="scrollbar">
<!-- the body control itself -->
<Canvas x:Name="PART_Body"/>
</ScrollViewer>
<!-- header part. Border and margin are used to make it not overlap vertical scrollbar -->
<Border Margin="0,0,18,18" ClipToBounds="True">
<Canvas x:Name="PART_Header">
<Canvas.RenderTransform>
<!-- bind X to the scrollbar X position -->
<TranslateTransform X="{Binding ElementName=scrollbar, Path=ContentHorizontalOffset, Converter={StaticResource InvertDoubleConverter}}"/>
<!-- InvertDoubleConverter is just a value converter which multiples incmoing double value by -1 -->
</Canvas.RenderTransform>
</Canvas>
</Border>
</Grid>