WPF BindingList loading no ui issues mvvm

Install-Package Microsoft.Extensions.DependencyInjection;
Install-Package CommunityToolkit.mvvm;

 

 

private async Task InitData()
{
    StatusMsg="Loading...";
    BooksBindingList=new BindingList<Book>();
    BooksBindingList.AllowEdit=true;
    BooksBindingList.AllowNew=true;
    BooksBindingList.AllowRemove=true;
    BooksBindingList.AddingNew+=BooksBindingList_AddingNew;

    await Task.Run(async () =>
    {
        List<Book> booksList=new List<Book>();
        for (int i = 0; i<10000000; i++)
        {
            Book bk = new Book()
            {
                Id=idService.GetID(),
                Name=nameService.GetName(),
                ISBN=iSBNService.GetISBN()
            };
            booksList.Add(bk);
            if (i%1000000==0)
            {
               await PopulateBooksBindingList(booksList);
            }                     
        }

        if(booksList.Count>0)
        {
            await PopulateBooksBindingList(booksList);
        }

        await Application.Current.Dispatcher.InvokeAsync(() =>
        {
            StatusMsg=$"Loaded {BooksBindingList.Count} items";
        });                
    });
    MessageBox.Show("Initialization finished!");
}

private async Task PopulateBooksBindingList(List<Book> booksList)
{
    await Application.Current.Dispatcher.InvokeAsync(() =>
    {
        var tempList = booksList.ToList();
        booksList.Clear();
        foreach (Book bk in tempList)
        {
            BooksBindingList.Add(bk);
        }
        StatusMsg=$"Loaded {BooksBindingList.Count} items";
    });
    await Task.Delay(1);
}

 

 

 

 

 

image

 

 

 

//app.cs
using Microsoft.Extensions.DependencyInjection;
using System.Configuration;
using System.Data;
using System.Windows;

namespace WpfApp14
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        ServiceProvider serviceProvider;
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            var services = new ServiceCollection();
            ConfigureServices(services);
            serviceProvider = services.BuildServiceProvider();

            var mainWin = serviceProvider.GetRequiredService<MainWindow>();
            mainWin?.Show();
        }

        private void ConfigureServices(ServiceCollection services)
        {
            services.AddSingleton<IIDService, IDService>();
            services.AddSingleton<INameService, NameService>();
            services.AddSingleton<IISBNService, ISBNService>();
            services.AddSingleton<MainWindow>();
            services.AddSingleton<MainVM>();
        }

        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);
        }
    }

}



//mainwindow.xaml
<Window x:Class="WpfApp14.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:WpfApp14"
        WindowState="Maximized"
        mc:Ignorable="d"
        Title="{Binding StatusMsg,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
        Height="450" Width="800">
    <Grid>
        <DataGrid ItemsSource="{Binding BooksBindingList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                  Width="{Binding DataContext.GridWidth,RelativeSource={RelativeSource AncestorType=Window}}"
                  Height="{Binding DataContext.GridHeight,RelativeSource={RelativeSource AncestorType=Window}}"
                  AutoGenerateColumns="False"
                  CanUserAddRows="False"
                  VirtualizingPanel.IsVirtualizing="True"
                  VirtualizingPanel.VirtualizationMode="Recycling">
            <DataGrid.Resources>
                <Style TargetType="DataGridRow">
                    <Setter Property="FontSize" Value="30"/>
                    <Setter Property="HorizontalAlignment" Value="Center"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="FontSize" Value="40"/>
                            <Setter Property="Foreground" Value="Red"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Id}"/>
                <DataGridTextColumn Binding="{Binding Name}"/>
                <DataGridTextColumn Binding="{Binding ISBN}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>


//mainwindow.cs
using CommunityToolkit.Mvvm.ComponentModel;
using System.ComponentModel;
using System.Diagnostics.Eventing.Reader;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp14
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public MainWindow(MainVM vm)
        {
            InitializeComponent();
            this.DataContext=vm;
            this.SizeChanged+=MainWindow_SizeChanged;
        }

        private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (DataContext is MainVM vm)
            {
                var fe = this.Content as FrameworkElement;
                if (fe!=null)
                {
                    vm.GridWidth=fe.ActualWidth;
                    vm.GridHeight=fe.ActualHeight;
                }
            }
        }
    }

    public partial class MainVM : ObservableObject
    {
        IIDService idService;
        IISBNService iSBNService;
        INameService nameService;
        public MainVM(IIDService idServiceValue, IISBNService iSBNServiceValue, INameService nameServiceValue)
        {
            idService=idServiceValue;
            iSBNService=iSBNServiceValue;
            nameService=nameServiceValue;
            InitData();
        }

        private async Task InitData()
        {
            StatusMsg="Loading...";
            BooksBindingList=new BindingList<Book>();
            BooksBindingList.AllowEdit=true;
            BooksBindingList.AllowNew=true;
            BooksBindingList.AllowRemove=true;
            BooksBindingList.AddingNew+=BooksBindingList_AddingNew;

            await Task.Run(async () =>
            {
                List<Book> booksList=new List<Book>();
                for (int i = 0; i<10000000; i++)
                {
                    Book bk = new Book()
                    {
                        Id=idService.GetID(),
                        Name=nameService.GetName(),
                        ISBN=iSBNService.GetISBN()
                    };
                    booksList.Add(bk);
                    if (i%1000000==0)
                    {
                       await PopulateBooksBindingList(booksList);
                    }                     
                }

                if(booksList.Count>0)
                {
                    await PopulateBooksBindingList(booksList);
                }

                await Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    StatusMsg=$"Loaded {BooksBindingList.Count} items";
                });                
            });
            MessageBox.Show("Initialization finished!");
        }

        private async Task PopulateBooksBindingList(List<Book> booksList)
        {
            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                var tempList = booksList.ToList();
                booksList.Clear();
                foreach (Book bk in tempList)
                {
                    BooksBindingList.Add(bk);
                }
                StatusMsg=$"Loaded {BooksBindingList.Count} items";
            });
            await Task.Delay(1);
        }

        private void BooksBindingList_AddingNew(object? sender, AddingNewEventArgs e)
        {
            BooksBindingList.Add(new Book()
            {
                Id = idService.GetID(),
                Name=nameService.GetName(),
                ISBN = iSBNService.GetISBN()
            });
        }

        [ObservableProperty]
        private double gridWidth;

        [ObservableProperty]
        private double gridHeight;


        [ObservableProperty]
        private BindingList<Book> booksBindingList;

        [ObservableProperty]
        private string statusMsg;
    }

    public class Book
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string ISBN { get; set; }
    }


    public interface IIDService
    {
        int GetID();
    }

    public class IDService : IIDService
    {
        int id = 0;
        public int GetID()
        {
            return ++id;
        }
    }

    public interface INameService
    {
        string GetName();
    }

    public class NameService : INameService
    {
        int idx = 0;
        public string GetName()
        {
            return $"Name_{++idx}";
        }
    }


    public interface IISBNService
    {
        string GetISBN();
    }

    public class ISBNService : IISBNService
    {
        int idx = 0;
        public string GetISBN()
        {
            return $"ISBN_{++idx}_{Guid.NewGuid():N}";
        }
    }
}

 

 

image

 

posted @ 2025-09-16 16:08  FredGrit  阅读(6)  评论(0)    收藏  举报