本网站已经多次询问过同样的问题,我已经阅读了大部分问题。但是我有一个特殊的问题(也许?)在经过几个小时的挣扎和阅读SO帖后无法弄明白。
问题是 - 只是解释了,我有一个包含Connect
按钮的WPF表单。如果按下此按钮,则该表单上必须出现一个文本块,显示“正在连接...”。按下按钮后,在相关的C#代码中完成一些握手操作,这需要一些时间。如果程序无法连接,则文本块必须更改为“失败!”。否则,它将变为“Succeed。”
现在,对于这个简单的问题,我在我的XAML中写道:
<Window x:Class="WpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button x:Name="connecting" Content="Connect" FontWeight="Bold" Click="startConnection"
Width="60" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="0"/>
<TextBlock x:Name="comm_stat" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"
Text="{Binding Content}"/>
</Grid>
</Window>
C#代码(灵感来自this answer):
using System;
using System.Text;
using System.Windows;
using System.ComponentModel;
namespace WpfTest
{
public class DynamicObj : INotifyPropertyChanged
{
public DynamicObj() : this(string.Empty) { }
public DynamicObj(string txt) { Content = txt; }
private string _name;
public string Content
{
get { return _name; }
set {
_name = value;
OnPropertyChanged("Content");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
comm_stat.DataContext = new DynamicObj();
}
private void startConnection(object sender, RoutedEventArgs e)
{
comm_stat.Text = "Connecting...";
bool connect2device = false;
// do the handshaking operations. the result is then assigned to connect2device
comm_stat.Text = connect2device ? "Succeed." : "Failed!";
// some other operations
}
}
}
现在的问题是,每当我点击按钮时,文本块中都不会出现文字。因为程序等待startConnection
方法到达其结尾,然后更新绑定的文本块。但我希望文本块在按下按钮后立即更改。我怎么能这样做?
答案 0 :(得分:3)
您可以使用BackgroundWorker
:
bool connect2device = false;
private void startConnection(object sender, RoutedEventArgs e)
{
comm_stat.Text = "Connecting...";
// do the handshaking operations. the result is then assigned to connect2device
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += DoWork;
worker.RunWorkerCompleted += Completed;
worker.RunWorkerAsync();
}
private void Completed(object sender, RunWorkerCompletedEventArgs e)
{
comm_stat.Text = connect2device ? "Succeed." : "Failed!";
}
private void DoWork(object sender, DoWorkEventArgs e)
{
//Change with actual work.
Thread.Sleep(1000);
connect2device = true;
}
一方面注意,您实际上不使用绑定来更改文本。 comm_stat.Text = "Connecting...";
直接设置text属性,并且根本不使用DynamicObj
对象。阅读一些关于MVVM的教程可能对你有好处。