[英]How can I refresh ItemsControl in wpf to show progress bar animations
這是我使用后台線程調用的合並算法:
public static class MergeAlghorithm
{
public static void mergeSort(int[] vector, int n)
{
int curr_size;
int left_start;
for (curr_size = 1; curr_size <= n - 1; curr_size = 2 * curr_size)
{
for (left_start = 0; left_start < n - 1; left_start += 2 * curr_size)
{
int mid_point = left_start + curr_size - 1;
int right_end = Math.Min(left_start + 2 * curr_size - 1, n - 1);
Merge(vector, left_start, mid_point, right_end);
}
}
}
public static void Merge(int[] vector, int left, int mid, int right)
{
int i, j, k;
int n1 = mid - left + 1;
int n2 = right - mid;
int[] L = new int[150];
int[] R = new int[150];
for (i = 0; i < n1; i++)
{
L[i] = new int();
L[i] = vector[left + i];
}
for (j = 0; j < n2; j++)
{
R[j] = new int();
R[j] = vector[mid + 1 + j];
}
i = 0;
j = 0;
k = left;
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
vector[k] = L[i];
var nr = L[i];
i++;
}
else
{
vector[k] = R[j];
j++;
}
k++;
}
while (i < n1)
{
vector[k] = L[i];
i++;
k++;
}
while (j < n2)
{
vector[k] = R[j];
j++;
k++;
}
}
}
這是我的MaiWindow代碼,在其中填充數組並使用backgound線程調用StarMerge方法以刷新UI:
public partial class MainWindow : Window
{
public static List<Number> items = new List<Number>();
public int[] a { get; set; } = new int[150];
public MainWindow()
{
InitializeComponent();
Random randomNumber = new Random();
// populate the array with random numbers
for (int i = 0; i < a.Length; i++)
{
a[i] = new int();
a[i] = randomNumber.Next(1, 200);
}
StartMerge(a, 100);// her I start the merge alghorithm
for (int i = 0; i < 100; i++)
{
items.Add(new Number() { Title = $"{a[i]}", Completion = a[i] });
}
SortedNumbers.ItemsSource = items;
}
// using the below method I tried to run the alghorithm in a background thread
public Thread StartMerge(int[] vector, int n)
{
var thread = new Thread(() => MergeAlghorithm.mergeSort(vector, n));
thread.IsBackground = true;
thread.Start();
return thread;
}
//with this I created a List on which I have the binding
public class Number
{
public string Title { get; set; }
public int Completion { get; set; }
}
}
還有XAML,我從Listitems綁定了Completion:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title=" MainWindow" Height="800" Width="400">
<Grid Margin="10">
<ItemsControl Name="SortedNumbers">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="5,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="800" />
</Grid.ColumnDefinitions>
<ProgressBar Grid.Column="1" Minimum="0" Maximum="600" Value="{Binding Completion}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
這就是我在MainWindow中得到的:
獲取動畫的一種簡單方法是將創建和分配項列表移至Merge方法中
public static void mergeSort(int[] vector, int n, ItemsControl ic)
{
int curr_size;
int left_start;
for (curr_size = 1; curr_size <= n - 1; curr_size = 2 * curr_size)
{
for (left_start = 0; left_start < n - 1; left_start += 2 * curr_size)
{
int mid_point = left_start + curr_size - 1;
int right_end = Math.Min(left_start + 2 * curr_size - 1, n - 1);
Merge(vector, left_start, mid_point, right_end);
List<Number> items = new List<Number>();
for (int i = 0; i < n; i++)
{
items.Add(new Number() { Title = $"{vector[i]}", Completion = vector[i] });
}
ic.Dispatcher.Invoke(() => ic.ItemsSource = items);
}
}
}
請注意,每次都會創建一個新的列表,否則,ItemsSource不會被更改,因此不會更新GUI。
如果重新創建列表,則每個循環都非常耗時(可能是由於數組大了),那么您就必須更改Number類,使其包含對要排序的數組的引用-您不能使用整數數組進行排序在這種情況下,因為不可能引用值類型。 然后,您可以像現在一樣在main方法中創建原始項目列表,並確保已強制ItemsControl更新每個循環。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.