2009-07-16 26 views
5

tôi đang tạo ra một GridView trong một phương pháp như vậy:Thay đổi thuộc tính cột GridView từ code-behind

GridView gridView = new GridView(); 
gridView.DataSource = reportData.Tables[0]; 
gridView.DataBind(); 

Sau này tôi đang xuất khẩu nó sang Excel và nó hoạt động tuyệt vời. Các cột đang được tạo tự động từ dữ liệu nguồn của tôi. Tôi muốn thay đổi các DataFormatString bất động sản của một số các cột tuy nhiên sau khi tôi databind và trước khi tôi xuất khẩu sang Excel. Tôi dường như không thể tìm thấy tài sản chính xác để thay đổi. Ai đó có thể chỉ cho tôi phương hướng đúng không?

Trả lời

7

Theo AutoGenerateColumns documentation:

Tùy chọn này cung cấp một cách thuận tiện để hiển thị tất cả các lĩnh vực trong các dữ liệu nguồn; tuy nhiên, bạn có giới hạn kiểm soát cách trường tự động tạo cột được hiển thị hoặc hoạt động.

Lưu ý: Tự động trường cột được tạo liên kết không phải là được thêm vào bộ sưu tập Cột.

Tôi mệt mỏi tìm kiếm những số AutoGeneratedField s không có may mắn.
tôi có thể nghĩ ra nhiều tùy chọn để đạt được điều đó (từ tồi tệ nhất để tốt nhất):

  1. Thêm sự kiện vào lưới (như RowDataBound), điều này sẽ cung cấp cho bạn truy cập vào các tế bào của hàng, nhưng không phải là quá tiện lợi.
  2. Không sử dụng AutoGeneratedField Tạo các cột này bằng tay, như trong:

    BoundField dateField = new BoundField(); 
    dateField.HeaderText = "Date"; 
    dateField.DataField = "date"; 
    dateField.DataFormatString = "{0:MMMM, yyyy}"; 
    gridView.Columns.Add(dateField); 
    

    tùy chọn này cho phép bạn bes kiểm soát các chức danh.

  3. Thêm lớp khác để định dạng và trình bày dữ liệu. Đây có lẽ là lựa chọn tốt nhất. Ngoài ra, theo cách đó bạn không phải sử dụng DataTables, GridView có thể bị ràng buộc với bất kỳ bộ sưu tập nào của đối tượng có thuộc tính công khai (ví dụ: List<Employee)) và AutoGeneratedField biến chúng thành cột.
    Tôi nghĩ đây là lựa chọn tốt nhất. Giả sử bạn có thể truy cập vào các cột tự động, sau đó là gì? Bạn sẽ phải tìm kiếm một cột dựa trên tên hoặc chỉ mục của nó, có vẻ như rất lộn xộn và làm tăng sự ghép nối.

Và, lưu ý cuối cùng, bạn nên nghĩ đến việc tạo tệp Excel bằng cách sử dụng API. Nó không phải là dễ dàng, nhưng các tệp HTML XLS ít tương thích với Excel 2007 - nó hiển thị thông báo cảnh báo rằng định dạng của tệp không tương thích với phần mở rộng, và tệ hơn, phanh tệp nếu nó được mở và lưu (có thể là Save As mặc dù), làm cho các tệp của bạn ít thân thiện với người dùng hơn.

+0

Sử dụng API yêu cầu Excel phải được cài đặt trên máy chủ ... chính xác? –

+0

Tôi tin như vậy nếu bạn đang sử dụng văn phòng interop. Nếu bạn tạo các tệp xlsx (của văn phòng 2007), về cơ bản chúng là một nhóm các tệp XML đã nén, vì vậy bạn có thể tạo chúng một cách tương đối dễ dàng (tốt nhất - tìm một thư viện). Bạn cũng có thể ghi vào Excel thông qua một chuỗi kết nối và db ole. Cách đơn giản nhất, btw (thoug mà không định dạng), là tạo một tệp CSV. – Kobi

+0

Tôi không thể cài đặt Excel trên máy chủ. Tôi không thể sử dụng các tệp xlsx vì chúng phải tương thích với 2000 và 2003. Định dạng là bắt buộc nên tôi không thể sử dụng csv. Tôi nghĩ rằng tôi có thể thử đề xuất thứ hai của bạn ở trên và tôi sẽ xem cách thức hoạt động. Cảm ơn! –

-1

Đây là vấn đề về cách asp.net hoạt động. Khi bạn tạo một số điều khiển (cột) trong một phương thức và đặt điều khiển này được đặt thành người dùng, lần sau người dùng đăng lại dữ liệu cho bạn, bạn không có quyền truy cập vào các cột đó vì chúng… không tồn tại. Mỗi lần bạn hiển thị trang web của mình, một đối tượng hoàn toàn mới (ví dụ) được tạo.
Cách duy nhất để có thể nhận được dữ liệu trong bài viết lại từ điều khiển tạo ra trước đó là tạo ra các điều khiển trong phương pháp Page_Init ...

+0

Tôi không chắc bạn hiểu những gì tôi đang cố gắng làm ở đây. Tôi đang tạo một thể hiện của lưới trong mã để xuất tức thì sang Excel. Postback không phải là một vấn đề. –

0

Ví dụ:

String newDataFormatString = "{0:d}"; 
BoundField bf = gridView.Columns[Index] as BoundField; 
if (bf != null) { 
    bf.DataFormatString = "{0}"; // workaround to sync with ViewState (it's documented) 
    bf.DataFormatString = newDataFormatString; 
} 
+0

Nó xuất hiện khi sử dụng AutoGenerateColumns bộ sưu tập Cột trống, mặc dù kết quả cuối cùng thực sự có cột. –

-1

Dưới đây là một chiết xuất từ ​​một nước xuất khẩu GridView tôi đã viết rằng chuyển đổi các điều khiển trong một GridView thành các chữ được tái tạo. Nó có thể là một số giúp đỡ:

 /// <summary> 
    /// Parses and cleans up data from the GridView controls collection 
    /// to make the data more suitable for Exported 
    /// </summary> 
    /// <param name="gv">The GridView to parse</param> 
    private void CleanUpControls(Control gv) 
    { 
     Literal l = new Literal(); 

     for (int i = 0; i < gv.Controls.Count; i++) 
     { 

      if (gv.Controls[i].GetType() == typeof (LinkButton)) 
      { 
       l.Text = (gv.Controls[i] as LinkButton).Text; 
       ReplaceWithLiteral(gv, l, i); 
      } 
      else if (gv.Controls[i].GetType() == typeof (ListControl)) 
      { 
       l.Text = (gv.Controls[i] as ListControl).SelectedItem.Text; 
       ReplaceWithLiteral(gv, l, i); 
      } 
      else if (gv.Controls[i].GetType() == typeof (CheckBox)) 
      { 
       l.Text = (gv.Controls[i] as CheckBox).Checked ? "True" : "False"; 
       ReplaceWithLiteral(gv, l, i); 
      } 
      else if (gv.Controls[i].GetType() == typeof (BooleanImage)) 
      { 
       l.Text = (gv.Controls[i] as BooleanImage).Value ? "True" : "False"; 
       ReplaceWithLiteral(gv, l, i); 
      } 
      else if (gv.Controls[i].GetType().ToString() == "System.Web.UI.WebControls.PagerTable") 
       ReplaceWithLiteral(gv, l, i); 

      else if (gv.Controls[i].GetType() == typeof (HyperLink)) 
      { 
       HyperLink hl = gv.Controls[i] as HyperLink; 
       if (MakeHyperLinksAbsolute) 
       { 
        if (hl != null) 
         hl.NavigateUrl = UrlHelper.MakeAbsoluteUrl(hl.NavigateUrl); 
       } 

       switch (TreatHyperLinksAs) 
       { 
        case HyperLinkMode.Text: 
         l.Text = hl.Text; 
         ReplaceWithLiteral(gv, l, i); 
         break; 

        case HyperLinkMode.NavigateUrl: 
         if (hl != null) l.Text = hl.NavigateUrl; 
         ReplaceWithLiteral(gv, l, i); 
         break; 

        case HyperLinkMode.ToolTip: 
         l.Text = hl.ToolTip; 
         ReplaceWithLiteral(gv, l, i); 
         break; 

        case HyperLinkMode.TextAndLink: 
         l.Text = String.Format("{0} ({1})", hl.Text, hl.NavigateUrl); 
         ReplaceWithLiteral(gv, l, i); 
         break; 

        case HyperLinkMode.HyperLink: 
         break; 
       } 
      } 

      if (gv.Controls[i].HasControls()) 
       CleanUpControls(gv.Controls[i]); 
     } 
    } 
+0

Điều này không thực sự hữu ích trong bối cảnh câu hỏi của tôi. Tôi chắc chắn nó rất hữu ích cho các ứng dụng khác. –

Các vấn đề liên quan