我正在开发第一个使用Prism 6的WPF应用程序。 单击按钮时,应该开始大约1-2分钟的操作。
我想在窗口内的所有其他控件的顶部显示一个半透明图层,并显示操作进度和取消按钮,如下面的图像和代码所示
<Window x:Class="TestingApplication.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://www.codeplex.com/prism">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Column="0">
<ContentControl x:Name="NavigationItemsControl"
prism:RegionManager.RegionName="MainNavigationRegion"
Grid.Column="0"/>
</Border>
<ContentControl prism:RegionManager.RegionName="MainContentRegion"
Grid.Row="1"/>
<Grid Grid.RowSpan="2" Background="#5555">
<Border BorderBrush="Gray" BorderThickness="1"
Width="400" Height="200" Background="White">
<StackPanel Margin="10">
<TextBlock Text="Loading... Please wait"
Margin="0,10" FontSize="18"/>
<ProgressBar HorizontalAlignment="Stretch" Height="40"/>
<Button Content="Cancel" HorizontalAlignment="Center"
Margin="0,10"/>
</StackPanel>
</Border>
</Grid>
</Grid>
</Window>
你能否给我任何建议,这是实现这一点并利用Prism和MVVM的最佳实践?
谢谢你, 纳迪亚
答案 0 :(得分:2)
我会使用eventAggrgator。
<ProgressBar HorizontalAlignment="Stretch" Height="40" Value{Binding ProgressBarValue}/>
public class ViewModel:BindableBase
{
private readonly IEventAggregator _eventAggregator;
public ViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.GetEvent<ProgressbarEvent>().Subscribe(PopulateProgress);
}
private void PopulateProgress(double value)
{
ProgressbarValue = value;
}
private double _progressbarValue;
public double ProgressbarValue
{
get { return _progressbarValue; }
set { SetProperty(ref(_progressbarValue),value); }
}
//this is how you would send event
public void SendProgress()
{
for (double i = 0; i < 100; i++)
{
_eventAggregator.GetEvent<ProgressbarEvent>().Publish(i);
}
}
}
public class ProgressbarEvent : PubSubEvent<Double> { }
确保在进行长时间操作时,您处于单独的线程中。
答案 1 :(得分:0)
我建议您ExtendedWPFToolkit BusyIndicator
。
你的XAML应该这样:
<extToolkit:BusyIndicator IsBusy="{Binding IsBusy}" BusyContent="Processing..." >
<extToolkit:BusyIndicator.ProgressBarStyle>
<Style TargetType="ProgressBar">
<Setter Property="IsIndeterminate" Value="False"/>
<Setter Property="Height" Value="15"/>
<Setter Property="Margin" Value="8,0,8,8"/>
<Setter Property="Value" Value="{Binding ProgressValue}"/>
</Style>
</extToolkit:BusyIndicator.ProgressBarStyle>
<ListBox ItemsSource="{Binding Persons}"/>
</extToolkit:BusyIndicator>
然后在ViewModel中实现布尔IsBusy
属性:
private bool isBusy;
public bool IsBusy
{
get { return isBusy; }
set
{
this.isBusy = value;
this.OnPropertyChanged("IsBusy");
}
}
然后向ViewModel添加ProgressValue
属性:
private int progressValue ;
public int ProgressValue
{
get { return progressValue ; }
set
{
this.progressValue = value;
this.OnPropertyChanged("ProgressValue ");
}
}
然后在DoWork
类的BackgroundWorker
lambda表达式中放置耗时的操作,以便不冻结UI:
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += (o, ea) =>
{
IsBusy = true;
//Do your heavy work here
worker.ReportProgress(10);
//Do your heavy work here
worker.ReportProgress(20);
//And so on
};
worker.ProgressChanged += (o,ea) =>
{
ProgressValue = e.ProgressPercentage;
};
worker.RunWorkerCompleted += (o, ea) =>
{
IsBusy = false;
};