Search code examples
c#wpfdata-bindingbackgroundworkercaliburn.micro

ProgressChanged in Caliburn micro doesn't update progressbar


I am trying to make a progress bar working in C# WPF but it doesn't work.

My xaml

<ProgressBar
    Height="15"
    Maximum="100"
    Minimum="0"
    Value="{Binding Path=Progress, Mode=OneWay}" />

My ViewModel

public ShellViewModel()
{
    loadAirportInfosBgWk = new BackgroundWorker();
    loadAirportInfosBgWk.DoWork += loadAirportInfosBgWk_DoWork;
    loadAirportInfosBgWk.ProgressChanged += loadAirportInfosBgWk_ProgressChanged;
    loadAirportInfosBgWk.RunWorkerCompleted += loadAirportInfosBgWk_RunWorkerCompleted;
    loadAirportInfosBgWk.WorkerReportsProgress = true;
    loadAirportInfosBgWk.RunWorkerAsync();
}

private void loadAirportInfosBgWk_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    IsBusy = false;
}

private void loadAirportInfosBgWk_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    Progress = e.ProgressPercentage;
    Console.WriteLine($"{e.ProgressPercentage}%");
}

private void loadAirportInfosBgWk_DoWork(object sender, DoWorkEventArgs e) 
{
   IsBusy = true;
   // Do stuff
   loadAirportInfosBgWk.ReportProgress(prog); // prog is int between 0 and 100
}

// _ variables are private variable at the top I omitted them
public bool IsBusy
{
    get { return _isBusy; }
    set { 
        _isBusy = value;
        NotifyOfPropertyChange(() => IsBusy);
    }
}


public int Progress
{
    get { return _progress; }
    set {
        if (_progress != value)
        {
            _progress = value;
            NotifyOfPropertyChange(() => Progress);
        }
    }
}

The curious thing is that the RunWorkerCompleted hide properly the loading component but the ProgressChanged doesn't update anything. But the console in the completed function log properly the value. I am really new to Caliburn micro and wish I could get it and do it properly. I looked on stack overflow but doesn't find a helping answer.

**EDIT : **

I tried to display the propoerty Progress in a Label and it is updating correctly, but not in the progressbar value. Maybe caused by the way I am using progress bar in a DataTemplate.

Detail xaml :

<xctk:BusyIndicator
Grid.RowSpan="2"
Margin="0,0,-0.2,25.6"
Panel.ZIndex="5"
DisplayAfter="0"
IsBusy="{Binding IsBusy}">
    <xctk:BusyIndicator.BusyContentTemplate>
        <DataTemplate>
            <StackPanel Margin="4">
                <TextBlock
                HorizontalAlignment="Center"
                FontWeight="Bold"
                Text="Downloading Email" />
                <StackPanel Margin="4">
                    <TextBlock Text="Chargement des données..." />
                    <ProgressBar
                    Height="15"
                    Maximum="100"
                    Value="{Binding Path=Progress}" />
                </StackPanel>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Button
                    Grid.Column="0"
                    Margin="0,0,2,0"
                    HorizontalAlignment="Right"
                    Content="Pause" />
                    <Button
                    Grid.Column="1"
                    Margin="2,0,0,0"
                    HorizontalAlignment="Left"
                    Content="Cancel" />
                </Grid>
            </StackPanel>
        </DataTemplate>
    </xctk:BusyIndicator.BusyContentTemplate>
    <xctk:BusyIndicator.OverlayStyle>
        <Style TargetType="Rectangle">
            <Setter Property="Fill" Value="#ffffeeee" />
        </Style>
    </xctk:BusyIndicator.OverlayStyle>
    <xctk:BusyIndicator.ProgressBarStyle>
        <Style TargetType="ProgressBar">
            <Setter Property="Visibility" Value="Collapsed" />
        </Style>
    </xctk:BusyIndicator.ProgressBarStyle>
</xctk:BusyIndicator>

Thanks, A.


Solution

  • Solved by adding BusyContent="{Binding}" in BusyIndicator :

    <xctk:BusyIndicator
        Grid.RowSpan="2"
        Margin="0,0,-0.2,25.6"
        Panel.ZIndex="5"
        BusyContent="{Binding}"
        DisplayAfter="0"
        IsBusy="{Binding IsBusy}">
       <!-- Code -->
    </xctk:BusyIndicator>