Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF ProgressBar with Value databinding

I'm trying to databind the value property of a ProgressBar in WPF. I have a button set up to increment the databound int property for the Value of the ProgressBar. When I push the button it should make the ProgressBar's Value count up from 1 to 100. However... it doesn't seem to be working and I am not sure what I am doing wrong. Here is my XAML...

<Window x:Class="ProgressBarExample2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="250" Width="400" Background="WhiteSmoke">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
    <Button Name="goButton" Height="30" Width="50" Margin="0,10,0,50" Click="goButton_Click">GO!</Button>
    <ProgressBar Name="progressBar" Width="300" Height="30" Value="{Binding Percent, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>

and here is my code behind...

public partial class MainWindow : Window, INotifyPropertyChanged
{
    #region INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChange(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion

    private int percent = 0;
    public int Percent
    {
        get { return this.percent; }
        set 
        {
            this.percent = value;
            NotifyPropertyChange("Percent");
        }
    }

    public MainWindow()
    {
        InitializeComponent();
    }


    private void goButton_Click(object sender, RoutedEventArgs e)
    {
        for (Percent = 0; Percent <= 100; Percent++)
        {
            Thread.Sleep(50);
        }
    }
}
like image 709
user1451495 Avatar asked Jan 10 '13 16:01

user1451495


1 Answers

The Thread.Sleep is blocking the UI thread and stopping the animation of the progress bar.

You can use the following to pause execution without blocking the UI thread. Replace your Thread.Sleep(50) call with Wait(50)

/// <summary>
/// Stop execution for a specific amount of time without blocking the UI
/// </summary>
/// <param name="interval">The time to wait in milliseconds</param>
public static void Wait(int interval)
{
    ExecuteWait(() => Thread.Sleep(interval));
}

public static void ExecuteWait(Action action)
{
    var waitFrame = new DispatcherFrame();

    // Use callback to "pop" dispatcher frame
    IAsyncResult op = action.BeginInvoke(dummy => waitFrame.Continue = false, null);

    // this method will block here but window messages are pumped
    Dispatcher.PushFrame(waitFrame);

    // this method may throw if the action threw. caller's responsibility to handle.
    action.EndInvoke(op);
}
like image 139
bic Avatar answered Oct 03 '22 16:10

bic