我是WPF和构建应用程序的新手,使用Mahapps ProgressRing控件在登录过程和随后的数据检索过程中显示加载动画。
我的问题是,无论我如何尝试,加载程序都不会显示。
我的ViewModel具有绑定ProgressRing IsActive标志的属性:
private bool loaderActive;
public bool LoaderActive
{
get { return loaderActive; }
set
{
loaderActive = value;
RaisePropertyChangedEvent("LoaderActive");
}
}
视图中的XAML控件:
<Controls:ProgressRing IsActive="{Binding LoaderActive}" Panel.ZIndex="1"/>
同一ViewModel中的方法(从按钮命令触发)将loaderActive
标志设置为true
,然后定义一个BackgroundWorker
来处理我想要的过程加载程序显示:
private void Login()
{
loaderActive = true;
bwLogin = new BackgroundWorker();
bwLogin.DoWork += BwLogin_DoWork;
bwLogin.RunWorkerCompleted += BwLogin_RunWorkerCompleted;
if (!bwLogin.IsBusy)
bwLogin.RunWorkerAsync();
}
该方法将触发并调用DoWork部分:
private void BwLogin_DoWork(object sender, DoWorkEventArgs e)
{
Thread.Sleep(5000); // making sure this takes longer
var token = ServerDataRepo.GetAuthorizationToken(userName, password);
if (!string.IsNullOrEmpty(token.Token))
{
GetServerList(token.Token);
}
}
最后,在另一个事件中我禁用了加载器:
private void BwLogin_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
loaderActive = false;
}
我的ViewModel继承自:
public abstract class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
加载器没有显示在预期的时间。我已经在XAML中尝试过TwoWay绑定(无论如何也不必这样做),尝试使用async Task
方法而不是BackgroundWorker方法将卸载过程实现到另一个线程,尝试在ViewModel构造函数中启用加载器loaderActive = true;
,确保它确实有效-确实如此,因此绑定起作用。
我还尝试用简单的TextBLock
代替控件,将其文本值绑定到ViewModel属性,然后以类似的方式填充该属性-两者均不显示。
UI线程未锁定-我检查了。据我所知,我正在UI线程中设置loaderActive
属性-除此之外,我没有在其他任何地方使用BackgroundWorker。
任何见识都会受到赞赏。
答案 0 :(得分:1)
elgonzo提供的解决方案:
请注意,只有在将值分配给属性时才执行属性设置器。直接对属性的后备字段进行赋值将不会执行属性设置器(自然,因为如果直接操作字段,则不涉及属性本身)。如果未执行属性设置器,则不会引发PropertyChangedEvent,因此绑定不会更新ProgressRing.IsActive ... – elgonzo
已将对属性bool LoaderActive
的分配更改为有效。