首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

GridView 導出 Excel 處理自定義控件:PrepareControlForExport 擴展模式

     編輯:關於ASP.NET

問題場景

GridView 模板列包含自定義控件(內含 DropDownList + 3 Label),導出時默認渲染為 DropDownList 第一項,而非顯示用的 Label 值。

標準導出工具擴展點

private static void PrepareControlForExport(Control control) {
    for (int i = 0; i < control.Controls.Count; i++) {
        Control current = control.Controls[i];
        
        // 內置控件處理
        if (current is LinkButton) ReplaceWithLiteral(current, ((LinkButton)current).Text);
        else if (current is ImageButton) ReplaceWithLiteral(current, ((ImageButton)current).AlternateText);
        else if (current is HyperLink) ReplaceWithLiteral(current, ((HyperLink)current).Text);
        else if (current is DropDownList) ReplaceWithLiteral(current, ((DropDownList)current).SelectedItem.Text);
        else if (current is CheckBox) ReplaceWithLiteral(current, ((CheckBox)current).Checked ? "True" : "False");
        
        // 遞歸處理子控件
        if (current.HasControls()) PrepareControlForExport(current);
    }
}

static void ReplaceWithLiteral(Control original, string text) {
    var parent = original.Parent;
    int index = parent.Controls.IndexOf(original);
    parent.Controls.RemoveAt(index);
    parent.Controls.AddAt(index, new LiteralControl(text));
}

自定義控件適配方案

方案一:實現 IExportable 接口(推薦)

public interface IExportable {
    string GetExportText();
}

public class MyCustomControl : CompositeControl, IExportable {
    private Label _displayLabel;
    // ...
    
    public string GetExportText() => _displayLabel.Text;
}

// PrepareControlForExport 中擴展
if (current is IExportable exportable) {
    ReplaceWithLiteral(current, exportable.GetExportText());
}

方案二:反射查找顯示屬性

else if (current.GetType().Name == "MyCustomControl") {
    var prop = current.GetType().GetProperty("DisplayText") 
            ?? current.GetType().GetProperty("Text");
    if (prop != null) {
        ReplaceWithLiteral(current, prop.GetValue(current)?.ToString() ?? "");
    }
}

方案三:ControlAdapter 適配器模式

// .browser 文件

  
    
      
    
  


// 適配器
public class MyCustomControlExportAdapter : ControlAdapter {
    protected override void Render(HtmlTextWriter writer) {
        var ctrl = (MyCustomControl)Control;
        writer.Write(ctrl.DisplayLabel.Text); // 導出時只輸出文本
    }
}

最佳實踐建議

  1. 優先實現 IExportable,編譯期檢查,零反射開銷
  2. 導出邏輯集中在 GridViewExportUtil,避免分散在各控件
  3. 複雜控件考慮 ControlAdapter,徹底分離渲染與導出邏輯
  4. 單元測試覆蓋導出輸出,防止界面改動破壞導出
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved