Home > OS >  C# MVVM looping and updating label with a fraction of a second timer
C# MVVM looping and updating label with a fraction of a second timer

Time:01-08

For the life of me, I cannot get the label to update progressively from 0 to 100. It goes straight to 100. I want to see it progress. I added a Thread.Sleep to 50. More than long enough to see.

I've added Fody for property change, so I don't have to add in all the fluff, I'll let the injection do it. But I did try it the traditional way, same result. Any help or insight would be most appreciated.

Thanks for everybody's attention and help on this.

I'm expecting to see the values from 0 to 100 iterate, with a fraction of a second in between.

Main window:

<Grid>
    <view:ProcessPartsView x:Name="ProcessPartsView" />
</Grid>

Controls ProcessPartsView:

<UserControl>
    <Grid>
        <Button x:Name="TaskButton" Command="{Binding FileLoadCommand}" />
        <Label x:Name="count_parts"  Content="{Binding PartCount}" />
    </Grid>
</UserControl>

Code-behind:

public partial class ProcessPartsView : UserControl
{
    public ProcessPartsView()
    {
        InitializeComponent();
        DataContext = new ProcessPartsViewModel();
    }
}

Commands:

using System;
using System.Windows.Input;
using TEST.ViewModels;

namespace TEST.Commands

public class FileLoadCommand : ICommand
{
    ProcessPartsViewModel _fileProcessViewModel;

    public FileLoadCommand( ProcessPartsViewModel viewModel) 
    { 
        _fileProcessViewModel = viewModel;
    }

    #region ICommand Members
    public event EventHandler? CanExecuteChanged
    {
        add    { CommandManager.RequerySuggested  = value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public bool CanExecute(object? parameter)
    {
        return true; // Button is always on
    }

    public void Execute(object? parameter)
    {
        _fileProcessViewModel.FileButtonClick();
    }
    #endregion
}

View model:

namespace TEST.ViewModels;

public class ProcessPartsViewModel : INotifyPropertyChanged
{
    private int _PartCount;             

    public event PropertyChangedEventHandler? PropertyChanged;
    public FileLoadCommand FileLoadCommand { get; set; }

    public int PartCount                
    {
        get { return _PartCount;  }
        set { _PartCount = value; }
    }

    // Initialize
    public ProcessPartsViewModel()
    {
        FileLoadCommand = new FileLoadCommand(this);  // Button on UI 
    }

    public void FileButtonClick()  // When the button is pressed in the view show dialog and processes selected file.
    {
        MessageBox.Show("I've been clicked!");
        ProcessParts(); 
    }

    public void ProcessParts()  
    {
        for (int i = 0; i < 100; i  )
        {
            PartCount  ;
            Thread.Sleep(50);
        }
    }
}

CodePudding user response:

Your ProcessParts() method is running synchronously and thus is blocking the UI thread.

You don't see any update, because the UI only changes after the method finished execution. That explains why it jumps directly to 100. You need to work with an asynchronous method.

Try using async/await instead. With async/await you don't block the UI thread:

public async void FileButtonClick()  // When the button is pressed in the view show dialog and processes selected file.
{
    MessageBox.Show("I've been clicked!");
    await ProcessPartsAsync(); 
}

public async Task ProcessPartsAsync()  
{
    for (int i = 0; i < 100; i  )
    {
        PartCount  ;
        await Task.Delay(TimeSpan.FromMilliseconds(50));
    }
}
  • Related