为什么没有设置ScrollOwner?

时间:2015-05-28 08:29:22

标签: c# wpf

我开发了测试驱动并希望测试,我实现IScrollInfo的控件返回正确的ScrollViewer。另外,我想在ScrollOwner上测试我的控件名为InvalidateScrollInfo

控件如下:

private class MyControl : UserControl, IScrollInfo
{
    public ScrollViewer ScrollOwner { get; set; }

    ... other code to implement IScrollInfo
}

我的测试(nunit)看起来像:

[Test]
public void Should_be_scrollable()
{
    var ControlToTest = new MyControl();
    var scrollViewer = new ScrollViewer { Content = ControlToTest };
    var window = new Window { Content = scrollViewer };
    window.Show();

    Assert.That(ControlToTest, Is.InstanceOf<IScrollInfo>());
    Assert.That(ControlToTest.ScrollOwner, Is.SameAs(scrollViewer));
}

但遗憾的是Assert.That(ControlToTest.ScrollOwner, Is.SameAs(scrollViewer));失败了,因为ScrollOwnernull

问题为什么ControlToTest.ScrollOwner为空?

我做了什么:我查看了ScrollOwner设置的位置。这发生在HookupScrollingComponents的{​​{1}}中,而ScrollContentPresenter则调用此OnApplyTemplate。根据我的理解,在测量元素时应用模板。这应该在显示窗口时完成。即使我添加window.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.Render);形式:

[Test]
public void Should_be_scrollable()
{
    var scrollViewer = new ScrollViewer { Content = ControlToTest };
    var window = new Window { Content = scrollViewer };
    window.Show();
    window.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.Render);

    Assert.That(ControlToTest, Is.InstanceOf<IScrollInfo>());
    Assert.That(ControlToTest.ScrollOwner, Is.SameAs(scrollViewer));
}
它没有帮助。 ScrollOwner仍然是null。为什么呢?

加分问题:如何测试InvalidateScrollInfo()上调用的scrollViewer

2 个答案:

答案 0 :(得分:2)

必须将PHP设置为CanContentScroll

比测试工作:

true

现在可以使用[Test] public void Should_be_scrollable() { var ControlToTest = new MyControl(); var scrollViewer = new ScrollViewer { Content = ControlToTest, CanContentScroll = true }; var window = new Window { Content = scrollViewer }; window.Show(); Assert.That(ControlToTest, Is.InstanceOf<IScrollInfo>()); Assert.That(ControlToTest.ScrollOwner, Is.SameAs(scrollViewer)); } 进行进一步测试。

回答Bonus问题:当您将ControlToTest.ScrollOwner更改为小于测试中的ControlToTest.ViewportHeight时,您可以检查ControlToTest.ExtentHeight属性以声明ControlToTest.ScrollOwner.ComputedVerticalScrollBarVisibility } 被称为。这可能看起来像:

ScrollOwner.InvalidateScrollInfo()

var scrollViewer = new ScrollViewer
{
    Content = ControlToTest,
    CanContentScroll = true,
    VerticalScrollBarVisibility = ScrollBarVisibility.Auto
};
var window = new Window { Content = scrollViewer, Height = 600 };
window.Show();
Assert.That(
    ControlToTest.ScrollOwner.ComputedVerticalScrollBarVisibility,
    Is.EqualTo(Visibility.Collapsed));

window.Height = 300;
Render();

Assert.That(
    ControlToTest.ScrollOwner.ComputedVerticalScrollBarVisibility,
    Is.EqualTo(Visibility.Visible));

答案 1 :(得分:0)

测试UI很棘手,WPF中发生的事情是,Actions被排队到Dispatcher上,只有在UI线程空闲后才会执行。所以windowWhow()之后的很多初始化都不会发生,直到你释放UI的线程来进行绑定/初始化,并将任务安排到调度程序上,执行断言的优先级非常低。在单元测试中这可能非常棘手。