簡體   English   中英

如何刷新WPF中的ItemsControl以顯示進度欄動畫

[英]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中得到的:

100個進度條

獲取動畫的一種簡單方法是將創建和分配項列表移至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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM