gpt4 book ai didi

c# - 文本更新未反射(reflect)在 WPF TextBlock 中 - 我错过了什么?

转载 作者:太空宇宙 更新时间:2023-11-03 13:21:59 26 4
gpt4 key购买 nike

概述

我是 WPF 的新手,我有一个带有文本区域、按钮和文本 block 的简单窗口。单击按钮时,我想将文本 block 更新为“开始..”或其他内容,运行一个需要几分钟的例程,最后将其更新为“完成”。

问题:

目前我的文本 block 只更新了“完成”消息。 :(

代码:

public partial class MainWindow : Window, INotifyPropertyChanged
{
private string myValue;
public string MyValue
{
get { return myValue; }
set
{
myValue = value;
RaisePropertyChanged("MyValue");
}
}

private void RaisePropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
public event PropertyChangedEventHandler PropertyChanged;
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}

private void ScriptToFileButton_Click(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
for (int i = 0; i < 50; i++)
{
System.Threading.Thread.Sleep(100);
MyValue = i.ToString();
}
});

MyValue = "Scripting, please wait..";
String text = DBObjectsTextArea.Text;
String[] args = text.Split(' ');
SQLScripter scripter = new SQLScripter();
scripter.script(args);
MyValue = "Done!";

}
private void Window_Closed(object sender, EventArgs e)
{
Application.Current.Shutdown();
}
}

XAML:

 <TextBox Height="109" HorizontalAlignment="Left" Margin="45,12,0,0" Name="DBObjectsTextArea" VerticalAlignment="Top" Width="418" />
<Button Content="Script To File" Height="23" HorizontalAlignment="Left" Margin="173,145,0,0" Name="ScriptToFileButton" VerticalAlignment="Top" Width="168" Click="ScriptToFileButton_Click" />
<TextBlock Height="56" HorizontalAlignment="Left" Margin="45,197,0,0" Name="StatusTextBlock" Text="{Binding Path=MyValue}" VerticalAlignment="Top" Width="409" />

类似链接:

我的代码基于此: How do I refresh visual control properties (TextBlock.text) set inside a loop?

最佳答案

您可以将您的事件处理程序更改为此...

   private void ScriptToFileButton_Click(object sender, RoutedEventArgs e)
{
String text = DBObjectsTextArea.Text;
Task t = new Task(() => PerformOnDispatcher(() => { MyValue = "Scripting, please wait.."; }));
ManualResetEvent mre = new ManualResetEvent(false);
t.ContinueWith((x) =>
{
// scripting code goes here...
mre.Set();
}, TaskContinuationOptions.LongRunning);

t.ContinueWith((y) =>
{
mre.WaitOne();
PerformOnDispatcher(() => { MyValue = "Scripting, please wait.."; });
});
t.Start();
}

这将工作分为三个阶段:告诉用户脚本已经开始,然后开始工作,然后告诉用户工作已经完成。同步由“ContinueWith”方法控制。此方法会等到前一个方法完成后再开始。

因为它在任务中,所以对 UI 的更改通过调度程序编码返回,调度程序使用单独的调度程序,因此不会被阻止。

最后一条语句 t.Start() 启动事件序列,因此单击按钮的用户体验不会受到阻塞的 UI 的影响。事件处理程序几乎立即返回。

如果工作进展得非常快,您仍然可能只看到“完成”,因为之前的消息在您有机会阅读之前就被覆盖了。所以调试这些东西的最好方法是将调试器锚定在这个语句上:

PropertyChanged(this, new PropertyChangedEventArgs(propName));

这将让您观察正在通过管道传输到绑定(bind)引擎的内容。

最后,为了使事件处理程序不那么困惑,以便专注于问题,我使用了一种方便的方法...

    private void PerformOnDispatcher(Action a)
{
Dispatcher.InvokeAsync(a);
}

对于工业级应用,这将是一种扩展方法或在属性 setter 中完成。

关于c# - 文本更新未反射(reflect)在 WPF TextBlock 中 - 我错过了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23810179/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com