首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在使用AvaloniaUI ScrollViewer时自动生成DataBinding?

如何在使用AvaloniaUI ScrollViewer时自动生成DataBinding?
EN

Stack Overflow用户
提问于 2020-07-20 18:58:18
回答 1查看 580关注 0票数 2

在我的AvaloniaUI应用程序中有这样的设置:

代码语言:javascript
运行
复制
<ScrollViewer VerticalScrollBarVisibility="Auto"
              AllowAutoHide="True"
              Name="MessageLogScrollViewer">
  <TextBlock HorizontalAlignment="Stretch"
             VerticalAlignment="Stretch"
             TextWrapping="NoWrap"
             Text="{Binding ReceivedMessages}"></TextBlock>
</ScrollViewer>

TextBlock基本上会显示日志消息,当我将新行添加到绑定到text属性的字符串时,我希望它能够自动滚动到底部。

ScrollViewer有一个名为ScrollToEnd()的方法,每当我更新文本时都需要调用该方法。因此,我试图在代码后面定义一个函数,如下所示:

代码语言:javascript
运行
复制
private ScrollViewer messageLogScrollViewer;    
public MainWindow()
{
    InitializeComponent();

    DataContext = new MainWindowViewModel(this);
    messageLogScrollViewer = this.FindControl<ScrollViewer>("MessageLogScrollViewer");
}

...

public void ScrollTextToEnd()
{
    messageLogScrollViewer.ScrollToEnd();
}

然后,我尝试从我的ViewModel中调用该函数:

代码语言:javascript
运行
复制
private string receivedMessages = string.Empty;
public string ReceivedMessages
{
    get => receivedMessages;
    set => this.RaiseAndSetIfChanged(ref receivedMessages, value);
}

...

private MainWindow _window;
public MainWindowViewModel(MainWindow window)
{
    _window = window;
}

...

ReceivedMessage += "\n";
ReceivedMessages += ReceivedMessage;
_window.ScrollTextToEnd(); // Does not work.

但是不幸的是,这个ScrollToEnd()函数需要从UI线程调用,因为我得到了一个异常:

System.InvalidOperationException:“从无效线程调用”

我的问题是,每当我通过ScrollViewer更新TextBlocks Text属性时,我如何自动将TextBlocks保存到最后?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-22 08:32:11

好吧,我想出来了,但把这个留在这里作为参考。

为了从UI上的另一个线程执行函数,需要调用

代码语言:javascript
运行
复制
Dispatcher.UIThread.InvokeAsync(_window.ScrollTextToEnd);

但是这只滚动到倒数第二行,因此,当我调用ScrollTextToEnd()时,该控件似乎还没有更新。因此,我在更新文本和调用滚动函数之间添加了一个短超时,如下所示

代码语言:javascript
运行
复制
ReceivedMessages += ReceivedMessage;
// A short timeout is needed, so that the scroll viewer will scroll to the new end of its content.
Thread.Sleep(10);
Dispatcher.UIThread.InvokeAsync(_window.ScrollTextToEnd);

它现在就是这样工作的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63002134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档