当在mvvm wpf中使用Application.Current.Dispatcher.BeginInvoke启动一个新
本文关键字:启动 一个 BeginInvoke Dispatcher wpf mvvm Current Application 当在 | 更新日期: 2023-09-27 18:03:07
我想显示一个弹出动画,当用户登录到应用程序。我的场景是这样的:我有一个主窗口,它的内容在后端绑定了一个属性SelectedVM
。此属性可以有两个值,一个LoginViewModel
和两个ContainerViewmodel
。
现在,我想在登录后显示这个弹出框,直到containerViewModel
中出现数据。
我一直在mainwindow.xaml
弹出。
我有一个单例类会话,其中我有IsOpen
的弹出属性。这是在调用数据加载功能时在LoginViewModel
中设置的。我可以看到通过复选框设置的属性,但弹出窗口没有显示。代码如下:
MainWindow.xaml
<Window><Window.Resources>
<DataTemplate DataType="{x:Type ViewModel:ContainerViewModel}">
<View:ContainerView></View:ContainerView>
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:LoginViewModel}">
<View:LoginScreenView></View:LoginScreenView>
</DataTemplate>
</Window.Resources>
<DockPanel>
<DockPanel.Background>
<ImageBrush ImageSource="Images/back.jpg"/>
</DockPanel.Background>
<Popup x:Name="WaitScreen"
Placement="Center"
Visibility="{Binding Path=CurrentSession.IsLoading}"
>
<local:LoadAnimation Background="Black" Margin="110,0,0,0"/>
</Popup>
<ContentControl Content="{Binding SelectedVM}"></ContentControl>
<!--<View:LoginScreenView DockPanel.Dock="Top" Height="100" Width="250" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>-->
</DockPanel></Window>
MainWindowViewModel.cs
public class MainWindowViewModel: ViewModelBase
{
public MainWindowViewModel()
{
try
{
this.CurrentSession.IsLoading = "Hidden";
this.CurrentSession.PropertyChanged += this.CurrentSession_PropertyChanged;
this.CurrentSession.VMBInstance = "LoginViewModel";
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
void CurrentSession_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if(e.PropertyName=="VMBInstance")
{
switch (this.CurrentSession.VMBInstance)
{
case "LoginViewModel":
{
this.SelectedVM = new LoginViewModel();
break;
}
case "ContainerViewModel":
{
this.SelectedVM = new ContainerViewModel();
break;
}
default:
{
this.SelectedVM = new LoginViewModel();
break;
}
}
}
}
private ViewModelBase selectedVM;
public ViewModelBase SelectedVM
{
get { return selectedVM; }
set { selectedVM = value; OnPropertyChanged(()=>this.SelectedVM); }
}
}
LoginViewModel.cs
class LoginViewModel :ViewModelBase
{
public LoginViewModel()
{
Submit = false;
this.CurrentSession.IsLoading = "Hidden";
//this.LoginCommand = new RelayCommand(o => this.worker.RunWorkerAsync(), o => !this.worker.IsBusy);
//this.worker.DoWork+=this.DoWork;
}
#region properties
private double _currentProgress;
public double CurrentProgress
{
get { return _currentProgress; }
private set
{
if (_currentProgress != value)
{
_currentProgress = value;
OnPropertyChanged("CurrentProgress");
}
}
}
private Jira Session { get; set; }
private string _userName;
public string UserName
{
get
{
if (_userName == String.Empty || _userName == null || _password == String.Empty || _password == null)
{
Submit = false;
}
return _userName;
}
set {
_userName = value;
if (value!=String.Empty || value!=null)
{
Submit = true;
}
OnPropertyChanged(() => this.UserName); }
}
private bool submit;
public bool Submit
{
get { return submit; }
set { submit = value; OnPropertyChanged(() => this.Submit);}
}
private string _password;
public string Password
{
get
{
if (_password == String.Empty || _password == null || _userName == String.Empty || _userName == null)
{
Submit = false;
}
return _password;
}
set
{
_password = value;
if (value != String.Empty || value != null)
{
Submit = true;
}
OnPropertyChanged(() => this.Password);
}
}
#endregion
#region Commands
public ICommand LoginCommand
{
get
{
try
{
return new RelayCommand(param => Login());
}
catch(Exception ed)
{
MessageBox.Show("Invalid Login Credentials");
return null;
}
}
}
public bool Login()
{
try
{
//this.Dispatcher.BeginInvoke(new Action(()=> this.CurrentSession.IsLoading=true));
Application.Current.Dispatcher.BeginInvoke
(new Action(() => {
this.CurrentSession.IsLoading = "Visible";
}));
this.Session = new Jira("http://jira.mcm.com:8080/", this.UserName, this.Password);
string test = this.Session.GetAccessToken();
if (this.Session == null)
{
return false;
}
this.CurrentSession.JiraObj = this.Session;
this.CurrentSession.UserName = this.UserName;
this.CurrentSession.VMBInstance = "ContainerViewModel";
//this.CurrentSession.IsLoading = true;
Application.Current.Dispatcher.Invoke(new Action(() => this.CurrentSession.IsLoading = "Hidden"));
//this.Dispatcher.BeginInvoke(new Action(() => this.CurrentSession.IsLoading = false));
return true;
}
catch (Exception ex)
{
MessageBox.Show("Invalid Login Credentials");
return false;
}
finally
{
this.Session = null;
}
}
#endregion
}
有人能告诉我如何使这个弹出可见在一个新的UI线程?
您的视图将IsLoading
绑定到弹出窗口的Visbility
属性,但该属性是string
。
将IsLoading
属性更改为Visbility
数据类型:
Application.Current.Dispatcher.BeginInvoke
(new Action(() => {
this.CurrentSession.IsLoading = Visibility.Visible;
}));
我通常检查的一些标准内容:
- 当我绑定时,我的上下文是否正确?
- 我的属性通知UI的变化(
INotifyPropertyChanged
) - 我的绑定方向正确吗?(单向、双向等)
- 我的转换器乱了吗?(如果我用的话)。断点并调试。
检查你的属性类型转换,因为你有可见性问题,你应该让它像
private Visibility isloading;
public Visibility Isloading
{
get{return isloading;}
set{isloading = value;
OnPropertyChanged("Isloading");
}
现在你想把它的可见性设置为true,只要输入
this.CurrentSession.Isloading = Visibility.Visible.
如果你想在默认情况下隐藏它,那么在创建属性时将其传递为折叠或隐藏,如我所示:
private Visibility isloading = Visibilty.Collapsed(orHidden);
public Visibility Isloading
{
get{return isloading;}
set{isloading = value;
OnPropertyChanged("Isloading");
}
首先,我会将IsLoading更改为布尔值(它要么正在加载,要么没有)。但是话虽如此,从字符串/布尔值到可见性的方式是通过一个转换器。
因为我建议你把IsLoading改成布尔型,下面是一个布尔型到可见性的转换器
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var b = value as bool?;
return b.GetValueOrDefault() ? Visibility.Visible : Visibility.Collapsed ;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is Visibility)) return false;
var b = (Visibility)value;
return b == Visibility.Visible ? true : false ;
}
}
然后可以在资源部分中包含转换器
你可以这样使用
<Popup Visibility="{Binding IsLoading, Converter={StaticResource BoolToVisibilityConverter}}"/>