i'm trying to report progress from ViewModel (MVVM Light) methods that are executed in a task. The ProgressViewModel contains a ProgressModel property that provides properties to describe the current state. Those properties are bound to an Xceed BusyIndicator
. So far, so good. But its not working as expected. The ProgressModel.IsRunning
is bound to BusyIndiciator.IsBusy
and toggles the visibility - that works. ProgressModel.Description
and ProgressModel.Percentage
are bound to a TextBlock.Text
/ProgressBar.Value
- but they are not updated...
So... since IsRunning
works, whats wrong with Description
and Progress
...?
// Model
public sealed class ProgressModel: ObservableObject
{
private string m_description;
private float m_percentage;
private bool m_running;
public string Description
{
get { return m_description; }
set { Set(ref m_description, value); }
}
public float Percentage
{
get { return m_percentage; }
set { Set(ref m_percentage, value); }
}
public bool IsRunning
{
get { return m_running; }
set{Set(ref m_running, value);}
}
public void Initiate()
{
Description = string.Empty;
Percentage = 0;
IsRunning = true;
}
}
// Command
private void DownloadWatch()
{
DispatcherHelper.UIDispatcher.Invoke(() =>
{
Progress.Initiate();
});
using (var watch = new PolarWatch())
{
watch.Connect();
for (var i = 0; i < watch.Sessions.Count; i++)
{
DispatcherHelper.UIDispatcher.Invoke(() =>
{
Progress.Description = $"Writing session data for '{session.DateTime}'...";
});
}
}
DispatcherHelper.UIDispatcher.Invoke(() =>
{
Progress.IsRunning = false;
});
}
// View
<xctk:BusyIndicator Name="Busy" IsBusy="{Binding Progress.IsRunning}">
<xctk:BusyIndicator.BusyContentTemplate>
<DataTemplate>
<Grid Width="150">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Progress.Description}"/>
<ProgressBar Grid.Row="1" Grid.Column="0" Value="{Binding Progress.Percentage}" Height="14" Margin="0,5,0,0"/>
</Grid>
</DataTemplate>
</xctk:BusyIndicator.BusyContentTemplate>
<xctk:BusyIndicator.ProgressBarStyle>
<Style TargetType="ProgressBar">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</xctk:BusyIndicator.ProgressBarStyle>
The DataContext
of the root element in the ItemTemplate
is not the same as the DataContext
of the control itself. Try this:
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding DataContext.Progress.Description, RelativeSource={RelativeSource AncestorType=xctk:BusyIndicator}}"/>
<ProgressBar Grid.Row="1" Grid.Column="0" Value="{Binding DataContext.Progress.Percentage,RelativeSource={RelativeSource AncestorType=xctk:BusyIndicator}}" Height="14" Margin="0,5,0,0"/>
Or set the DataContext
of the Grid
:
<Grid Width="150" DataContext="{Binding DataContext.Progress, RelativeSource={RelativeSource AncestorType=xctk:BusyIndicator}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Description}"/>
<ProgressBar Grid.Row="1" Grid.Column="0" Value="{Binding Percentage}" Height="14" Margin="0,5,0,0"/>
</Grid>