You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WPF中如何在Button_Click事件间传递Excel.Worksheet变量?

问题分析与解决方案

我来帮你拆解一下为什么会出现这个异常,以及怎么修复它:

问题根源

  • 全局Worksheet变量初始化错误:你在类里声明的Excel.Worksheet x = new Excel.Worksheet();是完全错误的。Office Interop的Worksheet对象不能直接通过new关键字实例化,必须从已打开的Workbook中获取(比如通过ActiveSheet或者Worksheets[index])。这就导致你的全局x从一开始就是一个无效的对象。
  • 局部变量遮蔽全局变量:在Button_Click方法里,你又声明了一个局部的Excel.Worksheet x,这会“遮蔽”掉全局的x变量——也就是说,你在这个方法里给x赋值,只是修改了局部变量,全局的x依然是那个无效的初始值。当你点击Button_Click_1或Button_Click_2时,调用Sort(x, 1)传入的是全局的无效x,自然会抛出System.InvalidCastException。
  • 为什么Button_Click_0能正常运行?:因为Button_Click_0是在方法内部完成了从打开Excel、获取有效Worksheet实例、调用排序到退出Excel的全流程,它使用的是方法内的局部x(这个x是从excel.ActiveSheet正确获取的有效实例),完全没有依赖全局变量,所以能正常执行。

修复方案

按照以下步骤修改你的代码:

  1. 修正全局变量声明:去掉错误的初始化,只声明变量,避免创建无效实例。
  2. 在Button_Click中给全局变量赋值:去掉局部变量的声明,直接给全局x赋值,确保后续排序方法能拿到有效的Worksheet实例。
  3. 优化Excel资源管理:避免重复打开Excel实例,同时在程序结束时手动释放COM对象,防止Excel进程残留后台。

修正后的完整代码示例

using Microsoft.Win32;
using System.IO;
using System;
using System.Windows;
using Excel = Microsoft.Office.Interop.Excel;

namespace Sorting {
    public partial class MainWindow : Window {
        int column, CounterRow;
        string filepath;
        // 修正全局变量:只声明,不初始化错误实例
        Excel.Application excelApp;
        Excel.Workbook excelWorkbook;
        Excel.Worksheet x;

        public MainWindow() {
            InitializeComponent();
        }

        private void Choose_Files_Button_Click(object sender, RoutedEventArgs e) {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = false;
            ofd.Filter = "All files (*.*)|*.*";
            ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            if (ofd.ShowDialog() == true) {
                ListBox_Files.Items.Clear();
                filepath = ofd.FileName;
                ListBox_Files.Items.Add(Path.GetFileName(filepath));
            }
            if (ListBox_Files.Items.Count != 0) 
                ListBox_Files.IsEnabled = Otworz.IsEnabled = true;
        }

        private void Button_Click_0(object sender, RoutedEventArgs e) {
            // 独立测试流程,增加资源释放逻辑避免进程残留
            Excel.Application excel = new Excel.Application();
            excel.Visible = true;
            excel.DisplayAlerts = false;
            Excel.Workbook workbook = excel.Workbooks.Open(filepath);
            Excel.Worksheet worksheet = excel.ActiveSheet as Excel.Worksheet;
            MessageBox.Show("select column");
            Sort(worksheet,1);
            MessageBox.Show("end");
            workbook.Close(false);
            excel.Quit();
            // 手动释放COM对象
            System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
        }

        private void Button_Click(object sender, RoutedEventArgs e) {
            excelApp = new Excel.Application();
            excelApp.Visible = true;
            excelApp.DisplayAlerts = false;
            excelWorkbook = excelApp.Workbooks.Open(filepath);
            // 直接给全局变量x赋值,不再声明局部变量
            x = excelApp.ActiveSheet as Excel.Worksheet;
        }

        private void Button_Click_1(object sender, RoutedEventArgs e) {
            // 增加空值判断,避免空引用异常
            if(x != null)
                Sort(x, 1);
        }

        private void Button_Click_2(object sender, RoutedEventArgs e) {
            if(x != null)
                Sort(x, 2);
        }

        private void Sort(Excel.Worksheet excel, int info) {
            Excel.Range rng = excel.Application.ActiveCell;
            column = rng.Column;
            Excel.Range userRange = excel.UsedRange;
            CounterRow = userRange.Rows.Count;
            Excel.Range range = excel.Range[excel.Cells[7, 1], excel.Cells[CounterRow - 1, 8]];
            if (info == 1) 
                range.Sort(range.Columns[column], Excel.XlSortOrder.xlAscending);
            else if (info == 2) 
                range.Sort(range.Columns[column], Excel.XlSortOrder.xlDescending);
        }

        // 窗口关闭时释放所有Excel资源
        protected override void OnClosed(EventArgs e) {
            base.OnClosed(e);
            if (x != null) {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(x);
            }
            if (excelWorkbook != null) {
                excelWorkbook.Close(false);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorkbook);
            }
            if (excelApp != null) {
                excelApp.Quit();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Kuba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:59:52