繁体   English   中英

为什么TextBlock.Text在设置内容时第一次(两次)没有更新? 以及如何解决/解决它?

[英]Why TextBlock.Text doesn't get updated the first time (of two) I set its content? and how to resolve/work-around it?

Clipboard.SetText(...)通常会在我的GUI中造成相当大的延迟。 现在暂时搁置“正确编程/设计”,我想告诉用户稍等片刻( #01行),然后让他/她知道成功还是失败( #06#10 )。 问题是我从没看到"Copying..."文本( #01行):

01| CopiedToClipboardTextBlock.Text = "Copying...";
02| try
03| {
04|     // May cause considerable delay and GUI-freeze for a while...
05|     Clipboard.SetText(textBlockContent);
06|     CopiedToClipboardTextBlock.Text = "Copied to clipboard:\n" + textBlockContent;
07| }
08| catch (Exception e)
09| {
10|     CopiedToClipboardTextBlock.Text = "Failed to copy to clipboard!";
11| }

所以我想-好的,也许GUI仅在事件处理程序返回时才更新(对我来说这没有意义...),所以我尝试了很多事情,其中​​包括:

  1. 使用PreviewMouseDoubleClick进行CopiedToClipboardTextBlock.Text = "Copying..." 没帮助...
  2. 使用其中Dispatcher.Invoke进入新线程的新线程(不要启动事件……我知道这很愚蠢……我很拼命)

(顺便说一句, Clipboard.SetText(...)的延迟是在它即将失败时发生的。失败是COMException: OpenClipboard Failed (Exception from HRESULT: 0x800401D0 (CLIPBRD_E_CANT_OPEN)) ,这在许多情况下几乎是不可避免的,但这不是这里的主要问题...)

更新:

这是我的解决方法:

CopiedToClipboardTextBlock.Text = "Copying...";

Exception resultException = null;
await Task.Run(() =>
{
    var t = new Thread(obj =>
    {
        try { Clipboard.SetText(textBlockContent); }
        catch (COMException e) { resultException = e; }
    });
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
    t.Join();
});

if (resultException == null)
    CopiedToClipboardTextBlock.Text = "Copied to clipboard:\n" + textBlockContent;
else
    CopiedToClipboardTextBlock.Text = "Failed to copy to clipboard!";

内部Thread是由于Clipboard.SetText(...)函数要求具有STA所致。

我不知道,对我来说似乎很冗长。 我怀疑有一个更简单的解决方案。

是的,GUI仅在事件处理程序返回时更新(因为事件处理程序在负责GUI更新的UI线程内被调用)。 要在长时间操作之前更新文本,应在后台线程中调用该操作。 因此,将释放事件处理程序,并刷新GUI。

尝试像这样设置剪贴板文本:

await Task.Run(() => Clipboard.SetText(textBlockContent));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM