C++/WinRT中GUI线程调用方法及ScrollViewer.ChangeView()失效解决
在C++/WinRT中调用ScrollViewer.ChangeView的正确姿势(UI线程切换)
我之前也踩过这个坑!你推测的原因完全正确——ScrollViewer.ChangeView()必须在UI线程执行才会有视觉效果,C++/WinRT里用CoreDispatcher::RunAsync()的写法其实很直观,我给你贴个完整的示例:
假设你在页面里有一个名为myScrollViewer的ScrollViewer控件,现在要在TextBox的TextChanged事件里触发滚动操作,代码可以这么写:
void MainPage::MyTextBox_TextChanged(TextBox const& sender, TextChangedEventArgs const& args) { // 获取ScrollViewer关联的CoreDispatcher auto dispatcher = myScrollViewer.Dispatcher(); if (dispatcher != nullptr) { // 切换到UI线程执行滚动操作 dispatcher.RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [this]() { // 示例:滚动到ScrollViewer最底部 // 参数分别是水平偏移、垂直偏移、缩放比例,不需要的传nullptr bool success = myScrollViewer.ChangeView( nullptr, myScrollViewer.ExtentHeight() - myScrollViewer.ViewportHeight(), nullptr); }); } }
几个需要注意的点:
- 务必先检查
dispatcher是否为空,防止空指针异常 - lambda里要访问类的成员控件(比如
myScrollViewer)的话,记得捕获this CoreDispatcherPriority可以按需选择,一般用Normal就够,如果是优先级高的更新可以用High
哪怕你的事件本身是在UI线程触发的,这么写也不会有问题——RunAsync如果检测到当前已经是UI线程,会直接执行lambda里的代码,不会有额外的性能开销。
内容的提问来源于stack exchange,提问作者user3743210
相关产品推荐
相关产品推荐

