WPF ListBox MVVM command export to excel,csv and json include all and multiply selected

install-package system.text.json
install-package epplus
//all
//xaml
<Window x:Class="WpfApp35.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:WpfApp35"
        WindowState="Maximized"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ListBox x:Name="lbx"
                 ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                 VirtualizingPanel.IsVirtualizing="True"
                 VirtualizingPanel.VirtualizationMode="Recycling"
                 VirtualizingPanel.CacheLengthUnit="Item"
                 SelectionMode="Multiple" >
            <ListBox.Resources>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Height" Value="200"/>
                    <Setter Property="FontSize" Value="30"/>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Height" Value="500"/>
                            <Setter Property="FontSize" Value="80"/>
                        </Trigger>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Height" Value="500"/>
                            <Setter Property="Foreground" Value="Red"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ListBox.Resources>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border>
                        <Border.Background>
                            <ImageBrush ImageSource="{Binding DataContext.ImgSource,
                                RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}}"/>
                        </Border.Background>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Grid.Row="0" Grid.Column="0"
                                       Text="{Binding Id}"/>
                            <TextBlock Grid.Row="0" Grid.Column="1"
                                       Text="{Binding Name}"/>
                            <TextBlock Grid.Row="0" Grid.Column="2"
                                       Text="{Binding Title}"/>
                            <TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3"
                                       Text="{Binding ISBN}"/>
                        </Grid>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Export All">
                        <MenuItem Header="Export To Excel"
                                  Command="{Binding ExportToExcelCommand}"
                                  CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                  AncestorType={x:Type ContextMenu}},Path=PlacementTarget.Items}"/>
                        <MenuItem Header="Export To CSV"
                                  Command="{Binding ExportToCSVCommand}"
                                  CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                  AncestorType={x:Type ContextMenu}},Path=PlacementTarget.Items}"/>
                        <MenuItem Header="Export To Json"
                                  Command="{Binding ExportToJsonCommand}"
                                  CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                  AncestorType={x:Type ContextMenu}},Path=PlacementTarget.Items}"/>
                    </MenuItem>
                    <MenuItem Header="Export Selected">
                        <MenuItem Header="Export Selected To Excel"
                                  Command="{Binding ExportToExcelCommand}"
                                  CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                  AncestorType={x:Type ContextMenu}},Path=PlacementTarget.SelectedItems}"/>
                        <MenuItem Header="Export Selected To CSV"
                                  Command="{Binding ExportToCSVCommand}"
                                  CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                  AncestorType={x:Type ContextMenu}},Path=PlacementTarget.SelectedItems}"/>
                        <MenuItem Header="Export Selected To Json"
                                  Command="{Binding ExportToJsonCommand}"
                                  CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                  AncestorType={x:Type ContextMenu}},Path=PlacementTarget.SelectedItems}"/>
                    </MenuItem>
                               
                </ContextMenu>
            </ListBox.ContextMenu>
        </ListBox>
    </Grid>
</Window>


//cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
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;
using System.Windows.Threading;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Win32;
using OfficeOpenXml;

namespace WpfApp35
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MainVM vm = new MainVM();
            this.DataContext = vm;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Task.Run(() =>
            {
                DIDemo();
            });
        }

        void DIDemo()
        {
            ServiceCollection services = new ServiceCollection();
            services.AddSingleton<IPrint, PrintService>();
            var builder = services.BuildServiceProvider();

            var printService = builder.GetRequiredService<IPrint>();
            for (int i = 0; i < 10000000; i++)
            {
                string str = $"{i + 1},{Guid.NewGuid().ToString("N")},{DateTime.Now.ToString("yyyyMMddHHmmssffff")}";
                printService.Print(str);
                Application.Current.Dispatcher.Invoke(() =>
                {
                    // Update UI or perform other actions on the UI thread if needed
                    lbx.Items.Add(str);
                    lbx.ScrollIntoView(lbx.Items[lbx.Items.Count - 1]);
                });
                Thread.Sleep(1000);
            }
        }
    }

    public class MainVM : INotifyPropertyChanged
    {
        public MainVM()
        {
            InitBooksCollection();
            InitCommands();
        }

        private void InitCommands()
        {
            ExportToExcelCommand = new DelCommand(ExportToExcelCommandExecuted);
            ExportToCSVCommand = new DelCommand(ExportToCSVCommandExecuted);
            ExportToJsonCommand = new DelCommand(ExportToJsonCommandExecuted);
        }

        private void ExportToJsonCommandExecuted(object? obj)
        {
            var items = (obj as System.Collections.IList)?.Cast<Book>()?.ToList();
            if (items != null && items.Any())
            {
                ExportBooksListToJson(items);
            }
        }

        private void ExportBooksListToJson(List<Book> items)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Json Files (*.json)|*.json|All Files (*.*)|*.*";
            if (sfd.ShowDialog() == true)
            {
                string jsonStr = ConvertListToJsonStr(items);
                //File.WriteAllBytes(sfd.FileName, Encoding.UTF8.GetBytes(jsonStr));
                File.WriteAllText(sfd.FileName, jsonStr, Encoding.UTF8);
                MessageBox.Show($"Exported {items.Count} records to {sfd.FileName}", "Export Json Successful", MessageBoxButton.OK, MessageBoxImage.Information);
            }            
        }

        private void ExportToExcelCommandExecuted(object? obj)
        {
            var items = (obj as System.Collections.IList)?.Cast<Book>()?.ToList();
            if (items != null && items.Any())
            {
                ExportListTToExcel(items);
            }
        }

        private void ExportListTToExcel(List<Book> booksList)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Excel Files (*.xlsx)|*.xlsx|All Files (*.*)|*.*";
            if (sfd.ShowDialog() == true)
            {
                var fileName = sfd.FileName;
                var destFileInfo = new FileInfo(fileName);
                ExcelPackage.License.SetNonCommercialPersonal("Fred");
                using (ExcelPackage excel = new ExcelPackage(destFileInfo))
                {
                    var worksheet = excel.Workbook.Worksheets.Add(typeof(Book).Name);
                    worksheet.Cells["A1"].LoadFromCollection(booksList, true, OfficeOpenXml.Table.TableStyles.Medium9);
                    excel.Save();
                }
                MessageBox.Show($"Exported {booksList.Count} records to {fileName}", "Export Successful", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }



        private void ExportToCSVCommandExecuted(object? obj)
        {
            var items = (obj as System.Collections.IList)?.Cast<Book>()?.ToList();
            if (items != null && items.Any())
            {
                ExportBooksListToCSV(items);
            }
        }

        private void ExportBooksListToCSV(List<Book> booksList)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "CSV Files (*.csv)|*.csv|All Files (*.*)|*.*";
            if (sfd.ShowDialog() == true)
            {
                StringBuilder csvContent = new StringBuilder();
                csvContent.AppendLine("Id,Name,Title,ISBN,ImgSource");
                foreach (var book in booksList)
                {
                    csvContent.AppendLine($"{book.Id},{book.Name},{book.Title},{book.ISBN},{book.ImgSource}");
                }
                File.WriteAllText(sfd.FileName, csvContent.ToString(), Encoding.UTF8);
                MessageBox.Show($"Exported {booksList.Count} records to {sfd.FileName}", "Export Successful", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        private string ConvertListToJsonStr(List<Book> booksList)
        {
            if (booksList == null || !booksList.Any())
            {
                return string.Empty;
            }
            JsonSerializerOptions options = new JsonSerializerOptions
            {
                WriteIndented = true, // For pretty printing
                Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping // To allow special characters
            };
            string jsonStr = JsonSerializer.Serialize(booksList, options);
            return jsonStr;
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string? propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private ObservableCollection<Book> booksCollection;
        public ObservableCollection<Book> BooksCollection
        {
            get => booksCollection;
            set
            {
                if (booksCollection != value)
                {
                    booksCollection = value;
                    OnPropertyChanged();
                }
            }
        }
        private void InitBooksCollection()
        {
            string dir = @"../../../Images";
            if (Directory.Exists(dir))
            {
                var imgs = Directory.GetFiles(dir);
                int imgsCount = imgs.Count();
                BooksCollection = new ObservableCollection<Book>();
                for (int i = 0; i < 100000; i++)
                {
                    BooksCollection.Add(new Book()
                    {
                        Id = i + 1,
                        Name = $"Name_{i + 1}",
                        Title = $"Title_{i + 1}",
                        ISBN = $"ISBN_{Guid.NewGuid()}",
                        ImgSource = GetImgSourceViaUrl(imgs[i % imgsCount])
                    });
                }
            }
        }

        private ImageSource GetImgSourceViaUrl(string imgUrl)
        {
            BitmapImage bmi = new BitmapImage();
            bmi.BeginInit();
            bmi.UriSource = new Uri(imgUrl, UriKind.RelativeOrAbsolute);
            bmi.EndInit();
            if (bmi.CanFreeze)
            {
                bmi.Freeze(); // Freeze the image to make it thread-safe
            }
            return bmi;
        }

        public DelCommand ExportToExcelCommand { get; set; }
        public DelCommand ExportToCSVCommand { get; set; }
        public DelCommand ExportToJsonCommand { get; set; }
    }

    public class Book
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Title { get; set; }
        public string ISBN { get; set; }
        [JsonIgnore]
        public ImageSource ImgSource { get; set; }
    }

    interface IPrint
    {
        void Print(string msg);
    }

    public class PrintService : IPrint
    {
        public void Print(string msg)
        {
            System.Diagnostics.Debug.WriteLine(msg);
        }
    }

    public class DelCommand : ICommand
    {
        private Action<object?> execute;
        private Predicate<object?> canExecute;
        public DelCommand(Action<object?> executeValue, Predicate<object?> canExecuteValue = null)
        {
            execute = executeValue;
            canExecute = canExecuteValue;
        }
        public event EventHandler? CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }

        public bool CanExecute(object? parameter)
        {
            return canExecute == null ? true : canExecute(parameter);
        }

        public void Execute(object? parameter)
        {
            execute(parameter);
        }
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

private void ExportListTToExcel(List<Book> booksList)
{
    SaveFileDialog sfd = new SaveFileDialog();
    sfd.Filter = "Excel Files (*.xlsx)|*.xlsx|All Files (*.*)|*.*";
    if (sfd.ShowDialog() == true)
    {
        var fileName = sfd.FileName;
        var destFileInfo = new FileInfo(fileName);
        ExcelPackage.License.SetNonCommercialPersonal("Fred");
        using (ExcelPackage excel = new ExcelPackage(destFileInfo))
        {
            var worksheet = excel.Workbook.Worksheets.Add(typeof(Book).Name);
            worksheet.Cells["A1"].LoadFromCollection(booksList, true, OfficeOpenXml.Table.TableStyles.Medium9);
            excel.Save();
        }
        MessageBox.Show($"Exported {booksList.Count} records to {fileName}", "Export Successful", MessageBoxButton.OK, MessageBoxImage.Information);
    }
}


private void ExportBooksListToCSV(List<Book> booksList)
{
    SaveFileDialog sfd = new SaveFileDialog();
    sfd.Filter = "CSV Files (*.csv)|*.csv|All Files (*.*)|*.*";
    if (sfd.ShowDialog() == true)
    {
        StringBuilder csvContent = new StringBuilder();
        csvContent.AppendLine("Id,Name,Title,ISBN,ImgSource");
        foreach (var book in booksList)
        {
            csvContent.AppendLine($"{book.Id},{book.Name},{book.Title},{book.ISBN},{book.ImgSource}");
        }
        File.WriteAllText(sfd.FileName, csvContent.ToString(), Encoding.UTF8);
        MessageBox.Show($"Exported {booksList.Count} records to {sfd.FileName}", "Export Successful", MessageBoxButton.OK, MessageBoxImage.Information);
    }
}


private string ConvertListToJsonStr(List<Book> booksList)
{
    if (booksList == null || !booksList.Any())
    {
        return string.Empty;
    }
    JsonSerializerOptions options = new JsonSerializerOptions
    {
        WriteIndented = true, // For pretty printing
        Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping // To allow special characters
    };
    string jsonStr = JsonSerializer.Serialize(booksList, options);
    return jsonStr;
}

 

posted @ 2025-06-08 20:46  FredGrit  阅读(16)  评论(0)    收藏  举报