[英]WPF - Exclude element from scrollbar effect in one way
有什么办法可以从某种滚动效果中排除某些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
包裹正文。 除了您的控件比屏幕(或外部控件)宽的情况外,此解决方案在所有方面都是完美的,因此也应允许水平滚动并且标题也应滚动。 您不能为此仅使用内部 scrollviwer,因为只有当水平滚动位于右边缘时,垂直滚动条才会可见。
您不能仅从垂直滚动中排除标题,但您可以模拟水平滚动。 你可以只用翻译变换来做到这一点。
<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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.