【发布时间】:2018-10-01 05:47:16
【问题描述】:
我正在使用 C# WPF。
我试图弄清楚是否有一种方法可以更新 XAML 元素,而无需使用您在以下代码中看到的 Refresh() 方法。
现在我正在封装与通过线程和 XAML 代码在 MainWindow 内启动的 C# doPlay() 方法相关的代码。
谁能建议一种无需使用Refresh() 方法即可更新进度条的方法?
private void doPlay()
{
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Red"));
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Blue"));
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Yellow"));
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Cyan"));
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Black"));
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Brown"));
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
TransfersXAML.ItemsSource = Transfers;
}));
Random rnd = new Random();
for (var i = 0; i < 100 * Transfers.Count; i++)
{
var next = rnd.Next(0, Transfers.Count);
mre.WaitOne();
int index = next;
if (Transfers[index].CurrentStep < 100)
{
Thread.Sleep(100);
Transfers[index].CurrentStep++;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
TransfersXAML.Items.Refresh();
}));
}
else i--;
}
}
XAML 相关代码:
<UniformGrid x:Name="DownLeftPanel" Grid.Column="2" Grid.Row="2">
<ListBox x:Name="TransfersXAML" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Transfers}">
<ListBox.ItemTemplate>
<DataTemplate>
<ProgressBar Height="30" Minimum="0" Maximum="{Binding NSteps}"
Value="{Binding CurrentStep}" Foreground="{Binding Color}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Get info" Click="GetTransferInfoClick" />
<MenuItem Header="Cancel" Click="CancelTransferClick" />
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
</UniformGrid>
我尝试简单地从 BeginInvoke 中删除 Action,但是这样不再显示条形图,即从第一个发布的代码中删除这些说明:
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
TransfersXAML.Items.Refresh();
}));
这个问题和下面一个有关系:Network threads blocking the GUI,特别是指问题本身下面的cmets。
【问题讨论】:
-
所以您正在尝试更新 CurrentStep 属性或者为什么需要刷新? Transfer 类是否实现了 INotifyPropertyChanged?