使用MVVM的WPF ProgressBar可见性不起作用
我有一个WPF窗口,显示两个日期之间的记录列表。我使用MVVM灯、实体框架和存储过程 当我运行命令以显示列表时,我希望显示一个进度条,以指示任务正在运行。查询完成后,我想隐藏进度条。 问题是进度条的可见性不能很好地工作。下面是我的代码:使用MVVM的WPF ProgressBar可见性不起作用,wpf,mvvm,Wpf,Mvvm,我有一个WPF窗口,显示两个日期之间的记录列表。我使用MVVM灯、实体框架和存储过程 当我运行命令以显示列表时,我希望显示一个进度条,以指示任务正在运行。查询完成后,我想隐藏进度条。 问题是进度条的可见性不能很好地工作。下面是我的代码: //XAML . . . . <StatusBar Grid.Row="2"> <StatusBarItem Width="300"> <TextBlock Text="{Binding
//XAML
.
.
.
.
<StatusBar Grid.Row="2">
<StatusBarItem Width="300">
<TextBlock Text="{Binding SBMessage, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</StatusBarItem>
<StatusBarItem Width="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Requête en cours..." Visibility="{Binding TaskInProgress, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, Converter={StaticResource booltovisibility}}" />
<ProgressBar
Visibility="{Binding TaskInProgress, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, Converter={StaticResource booltovisibility}}"
Width="100"
Height="20"
IsIndeterminate="True"
VerticalAlignment="Center"
Grid.Column="1"
/>
</Grid>
</StatusBarItem>
</StatusBar>
//ViewModel
bool _taskinprogress = false;
public bool TaskInProgress
{
get { return _taskinprogress; }
set
{
_taskinprogress = value;
RaisePropertyChanged("TaskInProgress");
}
}
public RelayCommand DisplaySimulationsListCommand
{
get
{
if (_splist == null)
_splist = new RelayCommand(DisplaySimulationsListCommandExecute);
return _splist;
}
}
private void DisplaySimulationsListCommandExecute()
{
SBMessage = "Exécution...";
TaskInProgress = true;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
DoItWithStoredProcedure();
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
SBMessage = ListSimulations.Count().ToString() + " Enregistrement(s) en : " + elapsedTime;
CurrentDisplayedTab = 1;
TaskInProgress = false;
//SBMessage = "Prêt";
}
private void DoItWithStoredProcedure()
{
try
{
using (UnitOfWork cx = new UnitOfWork())
{
var ls = cx.GetSimulationsPeriode(VMPeriode.Debut, VMPeriode.Fin).AsReadOnly();
ListSimulations = new ObservableCollection<Simulation>(ls);
CVS = (ListCollectionView)CollectionViewSource.GetDefaultView(ListSimulations);
RaisePropertyChanged("CVS");
}
}
catch (Exception ex)
{
Messenger.Default.Send<ExceptionMessageRefresh>(new ExceptionMessageRefresh(ex), "DoItWithStoredProcedure");
}
}
//Converter
public class BoolToVisiblityConverter : IValueConverter
{
#region Constructors
/// <summary>
/// The default constructor
/// </summary>
public BoolToVisiblityConverter() { }
#endregion
public bool Collapse { get; set; }
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool bValue = (bool)value;
if (bValue)
return Visibility.Visible;
else
{
if (Collapse)
return Visibility.Collapsed;
else
return Visibility.Hidden;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Visibility visibility = (Visibility)value;
if (visibility == Visibility.Visible)
return true;
else
return false;
}
#endregion
}
//XAML
.
.
.
.
//视图模型
bool\u taskinprogress=false;
公共布尔任务进程
{
获取{return\u taskinprogress;}
设置
{
_taskinprogress=值;
RaisePropertyChanged(“TaskInProgress”);
}
}
public Relay命令DisplaySimulationListCommand
{
得到
{
如果(_splist==null)
_splist=新的RelayCommand(DisplaySimulationListCommandExecute);
返回列表;
}
}
私有void DisplaySimulationListCommandExecute()
{
SBMessage=“执行…”;
TaskInProgress=true;
秒表秒表=新秒表();
秒表。开始();
DoItWithStoredProcedure();
秒表;
TimeSpan ts=秒表。已用时间;
string elapsedTime=string.Format(“{0:00}:{1:00}:{2:00}.{3:00}”,
时,分,秒,
ts.毫秒/10);
SBMessage=ListSimulations.Count().ToString()+“注册时间:”+elapsedTime;
CurrentDisplayedTab=1;
TaskInProgress=false;
//SBMessage=“Prêt”;
}
私有void DoItWithStoredProcedure()
{
尝试
{
使用(UnitOfWork cx=new UnitOfWork())
{
var ls=cx.GetSimulationsPeriode(VMPeriode.dunch,VMPeriode.Fin).AsReadOnly();
ListSimulations=新的可观测集合(ls);
CVS=(ListCollectionView)CollectionViewSource.GetDefaultView(ListSimulations);
RaisePropertyChanged(“CVS”);
}
}
捕获(例外情况除外)
{
Send(新的ExceptionMessageRefresh(ex),“DoitWithStoredProcess”);
}
}
//转换器
公共类BoolToVisiblityConverter:IValueConverter
{
#区域构造函数
///
///默认构造函数
///
public BoolToVisiblityConverter(){}
#端区
公共布尔折叠{get;set;}
#区域转换器成员
公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
bool bValue=(bool)值;
if(bValue)
返回可见性。可见;
其他的
{
如果(崩溃)
返回可见性。折叠;
其他的
返回可见性。隐藏;
}
}
公共对象转换回(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
可见性=(可见性)值;
如果(可见性==可见性.Visible)
返回true;
其他的
返回false;
}
#端区
}
提前感谢。您需要进行异步处理,因为一旦完成功能处理,所有UI级别的更改都将可用。在正常情况下,处理所需的时间可以忽略不计,因此这种情况并不明显 建议的修改:
// suggested changes start //
delegate void LongTaskDelegate();
private void DoItWithStoredProcedureAsync()
{
LongTaskDelegate del = new LongTaskDelegate(DoItWithStoredProcedure);
AsyncCallback callback = new AsyncCallback(LongTaskFinishedCallback);
IAsyncResult result = del.BeginInvoke(callback, null);
}
private void LongTaskFinishedCallback(IAsyncResult result)
{
TaskInProgress = false;
... some extra work
}
// suggested changes end //
private void DisplaySimulationsListCommandExecute()
{
...
TaskInProgress = true;
// call our new method declared above
DoItWithStoredProcedureAsync();
}
如果我们使用async/await模式,那么就没有类似于通知的事件,我们必须用TaskInProgress=false污染DoItWithStoredProcedure();这是可以做到的,但不是好的做法。我们当前的模式使用类似事件的通知,并通知我们长时间运行的任务完成。您需要进行异步处理,因为一旦完成功能处理,所有UI级别的更改都将可用。在正常情况下,处理所需的时间可以忽略不计,因此这种情况并不明显 建议的修改:
// suggested changes start //
delegate void LongTaskDelegate();
private void DoItWithStoredProcedureAsync()
{
LongTaskDelegate del = new LongTaskDelegate(DoItWithStoredProcedure);
AsyncCallback callback = new AsyncCallback(LongTaskFinishedCallback);
IAsyncResult result = del.BeginInvoke(callback, null);
}
private void LongTaskFinishedCallback(IAsyncResult result)
{
TaskInProgress = false;
... some extra work
}
// suggested changes end //
private void DisplaySimulationsListCommandExecute()
{
...
TaskInProgress = true;
// call our new method declared above
DoItWithStoredProcedureAsync();
}
如果我们使用async/await模式,那么就没有类似于通知的事件,我们必须用TaskInProgress=false污染DoItWithStoredProcedure();这是可以做到的,但不是好的做法。我们当前的模式使用类似事件的通知,并通知我们长时间运行的任务完成。您需要进行异步处理,因为一旦完成功能处理,所有UI级别的更改都将可用。在正常情况下,处理所需的时间可以忽略不计,因此这种情况并不明显 建议的修改:
// suggested changes start //
delegate void LongTaskDelegate();
private void DoItWithStoredProcedureAsync()
{
LongTaskDelegate del = new LongTaskDelegate(DoItWithStoredProcedure);
AsyncCallback callback = new AsyncCallback(LongTaskFinishedCallback);
IAsyncResult result = del.BeginInvoke(callback, null);
}
private void LongTaskFinishedCallback(IAsyncResult result)
{
TaskInProgress = false;
... some extra work
}
// suggested changes end //
private void DisplaySimulationsListCommandExecute()
{
...
TaskInProgress = true;
// call our new method declared above
DoItWithStoredProcedureAsync();
}
如果我们使用async/await模式,那么就没有类似于通知的事件,我们必须用TaskInProgress=false污染DoItWithStoredProcedure();这是可以做到的,但不是好的做法。我们当前的模式使用类似事件的通知,并通知我们长时间运行的任务完成。您需要进行异步处理,因为一旦完成功能处理,所有UI级别的更改都将可用。在正常情况下,处理所需的时间可以忽略不计,因此这种情况并不明显 建议的修改:
// suggested changes start //
delegate void LongTaskDelegate();
private void DoItWithStoredProcedureAsync()
{
LongTaskDelegate del = new LongTaskDelegate(DoItWithStoredProcedure);
AsyncCallback callback = new AsyncCallback(LongTaskFinishedCallback);
IAsyncResult result = del.BeginInvoke(callback, null);
}
private void LongTaskFinishedCallback(IAsyncResult result)
{
TaskInProgress = false;
... some extra work
}
// suggested changes end //
private void DisplaySimulationsListCommandExecute()
{
...
TaskInProgress = true;
// call our new method declared above
DoItWithStoredProcedureAsync();
}
如果我们使用async/await模式,那么就没有类似于通知的事件,我们必须用TaskInProgress=false污染DoItWithStoredProcedure();这是可以做到的,但不是好的做法。我们当前的模式使用类似事件的通知,并通知我们长期运行的任务完成情况。公认的答案是,在过去的日子里(在.NET Framework 4之前),孩子们需要步行上下学,他们是如何完成的。这是一个更具可读性的解决方案,它不需要大量的代码