[英]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仅在事件处理程序返回时才更新(对我来说这没有意义...),所以我尝试了很多事情,其中包括:
PreviewMouseDoubleClick
进行CopiedToClipboardTextBlock.Text = "Copying..."
。 没帮助... 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.