WPF Binding to TextBlock does not update target immediately
I don't think my question falls into any others here already so hopefully somebody can assist me.
I have a TextBlock binding set up using INotifyPropertyChnaged and it does work. The problem i am having is when it updates the target control (the TextBlock)
A quick run down of my code
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();
}
}
}
Now my issue is that my textblock displays "Loading Products" only after the method LoadProducts() is completed. It doesn't show "Loading Users" at all, so the target is only updating after everything has completed.
How do I get it to update immediately. The commented out bits was me just trying various things to try to force an update.
Any help would be greatly appreciated.
Kind regards,
Neill
The issue is that your retrieving of data is occurring on the same thread as your UI logic. This means that even though you change a property value and raise the OnPropertyChanged it is not re-evaluated until after your blocking data access is done. Instead you should use a BackgroundWorker. Here is a great article that walks through how you can use this:
http://elegantcode.com/2009/07/03/wpf-multithreading-using-the-backgroundworker-and-reporting-the-progress-to-the-ui/
Your StatusMessage
class should implement INotifyPropertyChanged:
Edit : Im pretty sure that your Window_ContentRendered
eventhanler blocks every UI update. I wrote a little sample that works for me:
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();
}
}
精彩评论