-1

In any .cs files I can call something like,

MessageBox.Show(
    "This is an example",
    "Example",
    MessageBoxButton.OK,
    MessageBoxImage.Warning
);

and that will spawn a messagebox over the current active window. I'm looking for a way to have a similar behavior but with a ProgressBar.

EDIT

To be more specific, I know I could use something like

<ProgressBar Minimum="0" Maximum="100" Name="pbStatus" IsIndeterminate="True" />

in my XAML file. But that would imply that I add it in all windows that will be performing the task. My goal is, therefore, to spawn it in the task's code directly if it's possible.

EDIT

I ended up writing a much more complex piece of code to achieve what I wanted. I will reference my solution on another question. See this https://stackoverflow.com/a/51212664/7692463.

scharette
  • 9,437
  • 8
  • 33
  • 67
  • To the down voters, feedback would be really appreciated. – scharette Jun 28 '18 at 14:48
  • 1) this isn't a question. 2) I can't see your code, did you try to do something? – Marco Salerno Jun 28 '18 at 14:50
  • 1
    1) I'm looking for a way to spawn a progressbar without using xaml if it's possible. 2) Since i'm asking for a way to do it I don't see how I can provide code (did research not tried solutions). – scharette Jun 28 '18 at 14:52
  • @MarcoSalerno also edited question – scharette Jun 28 '18 at 14:58
  • Stackoverflow provides answers only to users who try to program a solution and fail – Marco Salerno Jun 28 '18 at 14:58
  • @MarcoSalerno Stackoverflow actually answers question about programming. I tried to find solutions but I didn't. Sorry I don't have meaningful code to provide and I see your point. But please don't downvote any question where OP didn't provide code. Go see those top questions, you'll be surprise how many actually have code. – scharette Jun 28 '18 at 15:01
  • what do you mean by `task`? – default Jun 28 '18 at 15:06
  • Do you mean that you want a dialog box (modal or non modal) spawned, similar to how a messagebox is created? – default Jun 28 '18 at 15:06
  • @Default I didn't want to overload the question with information but if it can help, I'm running Powershell scripts in the background. During this process I'd like to spawn a progress bar so the user is not brought to think that the application is frozen. – scharette Jun 28 '18 at 15:08
  • but I asked if you want it in a dialog box or somewhere in your existing windows. You didn't answer my question – default Jun 28 '18 at 15:09
  • 1
    The reason why I'm asking is because a MessageBox is a `Window` but a ProgressBar is a `Control` - it needs to be contained in a `Window` - either an existing one or a new one. – default Jun 28 '18 at 15:11
  • You actually asked _what do you mean by task?_ so I answered. Now to answer your other question, I'm looking for a dialog box like the built-in messagebox. – scharette Jun 28 '18 at 15:12
  • @Default Oh I see, so I would need to create a window container for that `Progressbar` and show it whenever I perform my task ? – scharette Jun 28 '18 at 15:13
  • Yeah, I guess. It's not that difficult. You can create a new Window in your project which contains a `ProgressBar` and create and use it as a DialogBox, i.e. by calling [`ShowDialog()`](https://msdn.microsoft.com/en-us/library/system.windows.window.showdialog%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396). – default Jun 28 '18 at 15:31
  • 1
    @Default Seems legit. I'll look into it and try to implement it. – scharette Jun 28 '18 at 15:37

2 Answers2

1

Without doing the entire process for you, You could create a window that that opens on top of the active window with a progressbar on it then send the progress to it with an event.

I Just created this progress bar:

<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>

and the view model looks like :

 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();
        }
    }
}

the Event looks like

 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);
        }
    }
}

And the App.xaml.cs looks like:

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();
    }
}

Then i created a Button on the MainWindow that has and event handler that looks like:

    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();
        });

    }

Basically, this will open the progress bar window and close it when it Is done. You will have to figure out how to position the progress over the window that you want to run the progress on.

3xGuy
  • 2,235
  • 2
  • 29
  • 51
1

Instead of showing a MessageBox you could create a new window, set its Content property to a ProgressBar and call the window's Show or ShowDialog method depending on whether you want the window to be modal:

Window window = new Window();
window.Content = new ProgressBar()
{
    Minimum = 0,
    Maximum = 100, IsIndeterminate = true
};
window.Show();
mm8
  • 163,881
  • 10
  • 57
  • 88
  • I linked a working code that can spawn progress bar using async pattern. Linked in my question. Thanks again for your time. – scharette Jul 06 '18 at 17:36