我将 IList 绑定到 ListBox。列表中的每个项目都执行一个运行后台工作者操作的方法。这个类有一个 Progress 属性,然后绑定到 ListBox 的 DataTemplate。progress 属性实现 INotifyPropertyChange。
显然,这个想法比较简单:运行多个后台作业并将每个作业的进度报告给用户。我也在尝试提供其他属性,例如“JobStepText”或“IsBusy”。
我正在使用 MVVM 模式。ViewModel 创建列表并启动异步作业。
这行得通,但是我似乎遇到了同步问题,因为有时工作已经完成,而 on change 事件永远不会进入 UI。它的行为是完全随机的——有时它会在这里和那里,有时它不会。
在过去的几天里,我一直在谷歌上搜索这个问题,只是对如何纠正这个问题感到困惑。
<DataTemplate x:Key="ProgressTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Height="20" Stretch="Uniform" Source="{Binding Failed, Converter={StaticResource ProgressConverter}}"></Image>
<Image Height="20" RenderTransformOrigin="0.5, 0.5" Name="Spinner" Stretch="Uniform" Source="/Aps.SaasHr.M3Migration.Wpf;component/Images/spinner.jpg" Visibility="{Binding Failed, Converter={StaticResource ProgressConverter}}">
<Image.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource Spin360}" />
</EventTrigger.Actions>
</EventTrigger>
</Image.Triggers>
<Image.RenderTransform>
<RotateTransform Angle="0" />
</Image.RenderTransform>
</Image>
<ProgressBar Grid.Column="1" Height="40" IsEnabled="True" Value="{Binding Progress, Mode=OneWay}">
</ProgressBar>
<Border Grid.Column="1" Padding="5" VerticalAlignment="Center" TextBlock.Foreground="Black" TextBlock.FontWeight="Black" TextBlock.FontSize="18">
<StackPanel Orientation="Horizontal" >
<TextBlock FontSize="18" Foreground="White" Text="{Binding Config.ClassType, StringFormat='{}{0}\\'}" ></TextBlock>
<TextBlock FontSize="18" Text="{Binding Config.Name}" ></TextBlock>
<TextBlock Grid.Row="0" Text="{Binding Progress, StringFormat=' (%{0})', Mode=OneWay}"></TextBlock>
<TextBlock VerticalAlignment="Center" Text="{Binding CurrentText}" FontSize="12" Padding="3"></TextBlock>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
下面是启动工人的原因。在设置 LogText 等异步操作属性期间。
public void ProcessAsync(Action<RunWorkerCompletedEventArgs> complete)
{
_worker.RunWorkerCompleted += (o, e) =>
{
IsBusy = false;
if (e.Error != null)
{
Failed = true;
AddLogText("An unexpected error occured: " + e.Error.ToString());
}
else
{
Progress = 100;
Failed = false;
}
OnPropertyChanged("LogText");
complete(e);
};
IsBusy = true;
_worker.RunWorkerAsync();
}
并且来自列表的子类(带有背景工作者的工作者类)
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
#endregion
public string LogText
{
get { return _logText; }
set
{
_logText = value;
OnPropertyChanged("LogText");
}
}