在任何.cs
文件中,我都可以这样称呼,
MessageBox.Show(
"This is an example",
"Example",
MessageBoxButton.OK,
MessageBoxImage.Warning
);
,这将在当前活动窗口上方生成一个消息框。我正在寻找一种具有类似行为但使用ProgressBar
的方法。
编辑
更具体地说,我知道我可以使用
<ProgressBar Minimum="0" Maximum="100" Name="pbStatus" IsIndeterminate="True" />
在我的XAML文件中。但这意味着我将在执行任务的所有窗口中添加它。因此,我的目标是在可能的情况下直接在任务代码中生成它。
编辑
我最终写了一段复杂得多的代码来实现我想要的。我将在另一个问题上引用我的解决方案。参见此https://stackoverflow.com/a/51212664/7692463。
答案 0 :(得分:1)
您无需创建整个过程,就可以创建一个窗口,该窗口在活动窗口的顶部打开,并带有进度条,然后将事件发送给事件。
我刚刚创建了这个进度条:
<Window x:Class="ProgressBar.Views.ProgressBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
WindowStyle="None"
Title="ProgressBar" Height="25" Width="250">
<Grid VerticalAlignment="Center">
<ProgressBar Minimum="0" Maximum="100" Height="25" Value="{Binding Progress}"></ProgressBar>
</Grid>
视图模型如下所示:
public class ProgressViewModel:INotifyPropertyChanged
{
private int _progress;
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public ProgressViewModel()
{
ProgressBarEvent.GetInstance().ProgressChanged += (s, e) => Application.Current.Dispatcher.Invoke(()=> Progress = e);
}
public int Progress
{
get => _progress;
set
{
_progress = value;
OnPropertyChanged();
}
}
}
事件看起来像
public class ProgressBarEvent
{
private static ProgressBarEvent _instance;
public static ProgressBarEvent GetInstance()
{
if(_instance == null)
_instance = new ProgressBarEvent();
return _instance;
}
public EventHandler<int> ProgressChanged;
public EventHandler Show;
public EventHandler Close;
public ProgressBarEvent Start()
{
OnShow();
return this;
}
public ProgressBarEvent Stop()
{
OnStop();
return this;
}
private void OnShow()
{
if (Show is EventHandler show)
{
show.Invoke(this, new EventArgs());
}
}
private void OnStop()
{
if (Close is EventHandler close)
{
close.Invoke(this, new EventArgs());
}
}
public void SendProgress(int progress)
{
if (ProgressChanged is EventHandler<int> progressChanged)
{
progressChanged.Invoke(this, progress);
}
}
}
App.xaml.cs如下:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ProgressBarEvent.GetInstance().Show += ShowProgressBar;
ProgressBarEvent.GetInstance().Close += CloseProgressBar;
}
private Views.ProgressBar progressBarWindow;
private void CloseProgressBar(object sender, EventArgs e)
{
Application.Current.Dispatcher.Invoke(() => progressBarWindow.Close());
}
private void ShowProgressBar(object sender, EventArgs e)
{
progressBarWindow = new Views.ProgressBar();
var activeWindow = Application.Current.Windows.OfType<Window>().FirstOrDefault(x => x.IsActive);
progressBarWindow.Owner = activeWindow;
progressBarWindow.Show();
}
}
然后我在MainWindow上创建了一个按钮,该按钮具有和事件处理程序,如下所示:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ProgressBarEvent.GetInstance().Start();
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
ProgressBarEvent.GetInstance().SendProgress(i);
Thread.Sleep(100);
}
ProgressBarEvent.GetInstance().Stop();
});
}
基本上,这将打开进度栏窗口,并在完成后将其关闭。您将必须弄清楚如何将进度放置在要运行进度的窗口上。
答案 1 :(得分:1)
您可以创建一个新窗口,而不是显示MessageBox
,而是将其Content
属性设置为ProgressBar
,然后调用窗口的Show
或ShowDialog
方法取决于您是否希望窗口为模态:
Window window = new Window();
window.Content = new ProgressBar()
{
Minimum = 0,
Maximum = 100, IsIndeterminate = true
};
window.Show();