我认为我的问题不属于其他任何人,所以希望有人可以帮助我。
我使用INotifyPropertyChnaged设置了TextBlock绑定,它确实有效。我遇到的问题是它何时更新目标控件(TextBlock)
快速查看我的代码
namespace XYZ
{
public partial class Loading : Window
{
StatusMessage msg = StatusMessage.GetInstance();
public loading()
{
InitializeComponent();
this.DataContext = msg;
}
private void LoadBackEndUsers()
{
msg.Status = "Loading Users";
//txtStatus.GetBindingExpression(TextBlock.TextProperty).UpdateTarget();
//lblLoading.Focus();
this.txtStatus.DataContext = msg;
beUsers = new BackendUsers(Database);
allBEUsers = beUsers.GetAllUsers();
}
private void LoadProducts()
{
msg.Status = "Loading Products";
//txtStatus.GetBindingExpression(TextBlock.TextProperty).UpdateTarget();
//lblLoading.Focus();
this.txtStatus.DataContext = msg;
products = new Product(Database);
allProducts = products.GetAllProducts();
}
private void Window_ContentRendered(object sender, EventArgs e)
{
LoadBackEndUsers();
LoadProducts();
}
}
}
现在我的问题是,只有在LoadProducts()方法完成后,我的文本块才会显示“正在加载产品”。它根本不显示“正在加载用户”,因此目标只在一切完成后才更新。
如何让它立即更新。注释掉的是我只是尝试各种各样的东西来试图强制更新。
非常感谢任何帮助。
亲切的问候,
尼尔
答案 0 :(得分:3)
问题是您的数据检索发生在与UI逻辑相同的线程上。这意味着即使您更改属性值并引发OnPropertyChanged,也不会在阻塞数据访问完成之后重新评估它。相反,您应该使用BackgroundWorker。这是一篇很棒的文章,介绍了如何使用它:
答案 1 :(得分:2)
您的 StatusMessage
课程应实施INotifyPropertyChanged:
修改:我非常确定您的Window_ContentRendered
事件管理器会阻止每次更新UI。我写了一个适合我的小样本:
public partial class MainWindow : Window
{
StatusMessage msg = new StatusMessage();
public MainWindow()
{
InitializeComponent();
this.DataContext = msg;
}
private void LoadBackEndUsers()
{
Task.Factory.StartNew(() =>
{
this.Dispatcher.BeginInvoke(new ThreadStart(() => msg.Status = "Loading Users"), DispatcherPriority.Normal);
//Load users here:
Thread.Sleep(2000);
this.Dispatcher.BeginInvoke(new ThreadStart(() => msg.Status = "Users loaded"), DispatcherPriority.Normal);
// If users loaded start load products:
LoadProducts();
});
}
private void LoadProducts()
{
Task.Factory.StartNew(() =>
{
this.Dispatcher.BeginInvoke(new ThreadStart(() => msg.Status = "Loading Products"), DispatcherPriority.Normal);
//Load products here:
Thread.Sleep(2000);
this.Dispatcher.BeginInvoke(new ThreadStart(() => msg.Status = "Products Loaded"), DispatcherPriority.Normal);
});
}
private void Window_ContentRendered(object sender, EventArgs e)
{
LoadBackEndUsers();
//LoadProducts();
}
}