我有一个WPF UserControl
(位于ElementHost
内),ScrollViewer
包含ItemsControl
。 HorizontalScrollbarVisibility
设置为Auto
,因此如果不需要滚动,ScrollBar
将被隐藏。
我的要求是,如果显示/隐藏ScrollBar
,ElementHost
会相应地调整它的高度。为实现这一目标,我正在收听SizeChanged
事件,我获得了DesiredSize
中ScrollViewer
的{{1}},然后我通过EventHandler
到DesiredSize.Height
。
一种方法,这样做:ElementHost
可见(情况1),我放大窗口,直到ScrollBar
的所有项目都可见,ItemsControl
消失,{{1调整到降低的高度(情况2)。 <{1}}实际上在隐藏ScrollBar
时变小了。
另一方面,它不起作用:ElementHost
不可见(情况2),我缩小窗口大小,直到需要DesiredSize
并出现。 ScrollBar
保持不变,ScrollBar
无法调整(情况3)。
有什么想法吗?
这是ScrollBar
的xaml,有一些MVVM的东西,但是不要挂在这上面,关键是,为什么DesiredSize
在ElementHost
没有增加时{ {1}}出现了?它为什么只缩小?
Scrollviewer
ScrollViewer样式(基本上是默认的WPF):
DesiredSize
答案 0 :(得分:0)
我必须通过获取ScrollViewer的内容所需高度来计算所需的高度,并在可见时添加ScrollBar高度。
这对我来说仍然感觉有点尴尬,所以如果你有更好的解决方案,我会很乐意改变接受的答案。
public class HeightChangedBehavior : Behavior<ScrollViewer>
{
public ICommand HeightChangedCommand { get { return (ICommand)GetValue(HeightChangedCommandProperty); } set { SetValue(HeightChangedCommandProperty, value); } }
public static readonly DependencyProperty HeightChangedCommandProperty = DependencyProperty.Register("HeightChangedCommand", typeof(ICommand), typeof(HeightChangedBehavior), new PropertyMetadata(null));
protected override void OnAttached()
{
this.AssociatedObject.ScrollChanged += AssociatedObject_ScrollChanged;
base.OnAttached();
}
/// <summary>
/// Calculates the desired height for the scrollviewer, as the sum of its content
/// desired height and, if visible, the horizontal scrollbar height.
/// </summary>
void AssociatedObject_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
ScrollViewer sv = (ScrollViewer)sender;
// get content height
double height = ((FrameworkElement)sv.Content).DesiredSize.Height;
if (sv.ComputedHorizontalScrollBarVisibility == Visibility.Visible)
{
// add scrollbar height
height += (double)sv.FindResource(SystemParameters.HorizontalScrollBarHeightKey); // template of scrollbar should use this key
}
int intHeight = (int)Math.Ceiling(height); // whole pixels
// execute the command
ICommand cmd = this.HeightChangedCommand;
if (cmd != null && intHeight != sv.ActualHeight)
cmd.Execute(intHeight);
}
}