Home > Blockchain >  Databinding A Progress bar to a view model
Databinding A Progress bar to a view model

Time:09-14

I have a simple progress bar and status message textblock bound to a view model that should iterate in a foreach statement. it works fine in testing when a put a MessageBox in the foreach but if I take out the MessageBox the only status that's being captured is the last iteration and I can't determine what I need to do to correct that.

ViewModel -

    public class ExampleViewModel : INotifyPropertyChanged
    {        
        public RelayCommand<IList> Submit { get; }
        
        private KeyValuePair<Model, string[]> _selectedItem;
        public KeyValuePair<Model, string[]> SelectedItem
        {
            get => _selectedItem;
            set
            {
                _selectedItem = value;
                RaisePropertyChanged(nameof(SelectedItem));
            }
        }

        public ExampleViewModel()
        {
            Submit = new RelayCommand<IList>(ExecuteSubmit);
        }

        private void ExecuteSubmit(IList selectedItems)
        {
            string[] examples = new string[] {"a", "b", "c"};

            double percentAge = 100/examples.Count;

            if (examples.Count > 0)
            {
                foreach (var ex in examples)
                {
                    CurrentProgress = CurrentProgress   percentAge;
                    MessageBox.Show("Step "   ex);  // Status and Progress Bar update when this isn't commented out
                    //   Thread.Sleep(1000);
                    StatusMessages = "Option "   ex;
                }
            }
            return;
        }

        #region Status Fields
        private string _statusMessages;
        public string StatusMessages
        {
            get => _statusMessages;
            set
            {
                if (_statusMessages != value)
                {
                    _statusMessages = value;
                    RaisePropertyChanged(nameof(StatusMessages));
                }
            }
        }

        private double _currentProgress;
        public double CurrentProgress
        {
            get => _currentProgress;
            set
            {
                if (_currentProgress != value)
                {
                    _currentProgress = value;
                    RaisePropertyChanged(nameof(CurrentProgress));
                }
            }
        }
        #endregion

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

XAML -

            <ProgressBar Value="{Binding CurrentProgress, Mode=OneWay}"
                Margin="5,5" Height="10" Width="240" HorizontalAlignment="Left"/>
            <TextBlock Margin="5,5" Height="15" Width="240" TextWrapping="Wrap"
                Foreground="Red"
                Text="{Binding StatusMessages}"></TextBlock>

CodePudding user response:

Calling Thread.Sleep(1000); on UI thread is wrong.. It freezes the UI and once the freeze ends it will start a new freeze so it could not even update any of the UI elements that are bound with the properties.. You can use DispatcherTimer instead

Replace

foreach (var ex in examples)
{
    CurrentProgress = CurrentProgress   percentAge;
    MessageBox.Show("Step "   ex);  // Status and Progress Bar update when this isn't commented out
    //   Thread.Sleep(1000);
    StatusMessages = "Option "   ex;
}

With

var timer = new DispatcherTimer
{
    Interval = TimeSpan.FromSeconds(1)
};
int ticksCount = 0;
var ticksLimit = examples.Count;
timer.Tick  = (_, _) =>
{
    ticksCount  ;
    if (ticksCount > ticksLimit)
        timer.Stop();
    else
    {
        var ex = examples[ticksCount - 1];
        CurrentProgress = CurrentProgress   percentAge;
        StatusMessages = "Option "   ex;
    }
};
timer.Start();
  • Related