简体   繁体   English

如何刷新WPF中的ItemsControl以显示进度栏动画

[英]How can I refresh ItemsControl in wpf to show progress bar animations

Here is my merge algorithm which I call using a background Thread: 这是我使用后台线程调用的合并算法:

 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++;

            }
        }
    }

Here is my MaiWindow code where I populate the array and call the StarMerge method with a backgound thread in order to refresh the UI : 这是我的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; }
                }

            }

And the XAML where I have the binding on Completion from the Listitems: 还有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>

And this is what I get in MainWindow: 这就是我在MainWindow中得到的:

100个进度条

A simple way to get the animation would be to move creating & assigning the items list into the Merge method 获取动画的一种简单方法是将创建和分配项列表移至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);
    }
  }
}

Note that a new List is created each time, otherwise the ItemsSource will not be seen to change so the GUI will not be updated. 请注意,每次都会创建一个新的列表,否则,ItemsSource不会被更改,因此不会更新GUI。

If recreating the list each loop were to be too time consuming (maybe due to much bigger arrays) then you would have to change the Number class so that it contained references to the array you are sorting - you could not use an integer array for sorting in that case, as it is not possible to make references to value types. 如果重新创建列表,则每个循环都非常耗时(可能是由于数组大了),那么您就必须更改Number类,使其包含对要排序的数组的引用-您不能使用整数数组进行排序在这种情况下,因为不可能引用值类型。 You could then create the original items list in your main method as you do now & just ensure that the ItemsControl is forced to update each loop. 然后,您可以像现在一样在main方法中创建原始项目列表,并确保已强制ItemsControl更新每个循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM