2010-02-08 21 views
7

Trong điều khiển lặp lại, có cách nào để loại bỏ các mục nhất định trước khi trang được hiển thị không?Điều khiển lặp lại - Hủy liên kết cho mục cụ thể

Hiện tại chúng tôi có một bộ sưu tập các mục bị ràng buộc với bộ lặp và nếu mục đó không thuộc ngôn ngữ hiện tại, chúng tôi sẽ ẩn mục đó.

Tôi muốn có thể thực hiện đếm trên bộ lặp và nhận lại số hợp lệ. Số đếm không bao gồm các mục bị ẩn.

Có thể loại bỏ các mục cụ thể trong sự kiện ItemDataBound không?

Cập nhật

Đối với mỗi mục trong bộ sưu tập chúng ta ràng buộc, chúng tôi kiểm tra cơ sở dữ liệu trong ItemDataBound để biết thêm thông tin về mục, chẳng hạn như ngôn ngữ vv Điều này hiện đang dừng lại chúng ta ra khỏi sự ràng buộc lọc dữ liệu trước khi ràng buộc nó.

Trả lời

2

Tôi đồng ý với các câu trả lời khác - giải pháp tốt nhất (cho cả hiệu suất và mã rõ ràng) là thiết kế lại trang để bạn có thể lọc các mục không hợp lệ ra trước khi dữ liệu.

Hầu hết các nguồn dữ liệu không cho phép chúng tôi xóa các mục của chúng trong khi ASP.NET đang lặp lại chúng. Ví dụ: nếu bạn liên kết với một đơn giản chung chung List<T> và bạn xóa một mục trong khi lặp lại, danh sách sẽ ném một số InvalidOperationException.

Trong các trường hợp khác, ASP.NET thực sự lặp lại bản sao của nguồn dữ liệu. Nếu bạn liên kết với DataTable, ASP.NET sử dụng bản sao nội dung (DataView mặc định) thay vì tự lặp lại các hàng nguồn - bạn có thể xóa các mục khỏi nguồn dữ liệu cơ bản trong khi lặp lại, nhưng nó không ảnh hưởng đến hoạt động databinding .

Nếu lọc các mục trước thực sự không phải là một lựa chọn, giải pháp hiện tại của bạn là tốt: chỉ cần ẩn các mục! Nếu bạn cần phải nhận được số lượng chính xác trên hết, theo dõi số lượng các mục không hợp lệ trong xử lý ItemDataBound của bạn và phơi bày nó như một tài sản trang cấp:

if (IsInvalid(args.Item.DataItem)) { 
    this.invalidItemCount++; 
    // code to hide the current item 
} 
+0

Tôi muốn thiết kế lại cách các trang hoạt động nhưng chúng tôi đang sử dụng EPiServer làm CMS và theo như tôi đã tìm thấy, hiện tại là cách tốt nhất mà tôi có thể tìm thấy. Tôi hiện đang theo dõi sugestion cuối cùng của bạn để trưng ra một tài sản Đếm và cho rằng nó có giá trị. Có thể phải gắn bó với điều đó. Cảm ơn vi đa trả lơi :) –

3

Một giải pháp thích hợp hơn có thể là lọc bộ sưu tập bị ràng buộc nếu không có nhu cầu cụ thể trong các mục bị ẩn đó. Một cái gì đó như

items.Where(i => i.IsInLanguage(currentLanguage)); 

Cập nhật:

Đối với tôi, tôi muốn sử dụng phương pháp này:

var items = db. 
     Where(i => i.IsInLanguage(currentLanguage)). 
     Where(i => i.SomeField == anotherFilterParameter); 

repeater.DataSource = items; 
repeater.DataBind(); 

Vì vậy, tất cả các bộ lọc được áp dụng trước

này sẽ làm giảm số lượng round- các chuyến đi đến cơ sở dữ liệu cũng sẽ phát huy hiệu suất tốt hơn

+0

Tôi sẽ cập nhật OQ của mình nhưng về cơ bản, chúng tôi không biết mục nào sẽ được đặt thành hiển thị vv cho đến khi sự kiện ItemDataBound. Mỗi mục có một ID và chúng tôi đi đến DB để biết thêm chi tiết tại thời điểm đó. –

+0

Điều gì sẽ xảy ra trên ItemDataBound giúp lọc có thể? Ngôn ngữ hiện tại của bạn chỉ có sẵn vào thời điểm đó? –

+0

vâng. Về cơ bản chúng tôi có một cái gì đó gọi là một bộ sưu tập của "trang" ID và như mỗi mục bị ràng buộc, chúng tôi đi đến cơ sở dữ liệu, tìm hiểu xem đó là một phần của ngôn ngữ hiện tại và nếu không, ẩn mục. –

2

Tại sao không lọc er nguồn dữ liệu trước khi ràng buộc. Giả sử bạn đang sử dụng một số đối tượng tùy chỉnh:

myRepeater.DataSource=repository.getItems().Where(item=>item.Language==CurrentLanguage); 

Nếu bạn không cần chúng không ràng buộc chúng ngay từ đầu.

Cập nhật

Nếu nó ở tất cả các thể bạn probally nên kéo rằng thông tin từ trả trước DB. Những danh sách này có lớn không? Nếu nhấn db một lần cho mỗi mục trong danh sách sẽ hiển thị dưới dạng vấn đề hiệu suất.

2

Câu trả lời là rất dễ dàng, bạn chỉ cần thiết lập các Visible thuộc tính vào false trên mục và nó sẽ không được hiển thị. Trong ví dụ này tôi loại bỏ các mục từ danh sách sản phẩm mà chỉ có sẵn cho khách hàng mới nếu người dùng hiện nay có một lịch sử mua hàng:

void rpt_ItemDataBound(object sender, RepeaterItemEventArgs e) 
     { 
      if (!userHasPurchaseHistory) { return; } 
      // filter out products only allowed for new members 
      if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
      { 
       System.Data.Common.DbDataRecord rec = (System.Data.Common.DbDataRecord)e.Item.DataItem; 
       if (rec != null) 
       { 
        bool newMemberOnly = Convert.ToBoolean(rec["NewMemberOnly"]); 
        if (newMemberOnly) { e.Item.Visible = false; } 
       } 
      } 

     } 

Lưu ý rằng ở trên là databound đến một IDataReader, bạn có thể cần phải cast các e.Item.DataItem đến một đối tượng khác nhau tùy thuộc vào những gì bạn đang ràng buộc. Lưu ý rằng tôi chắc chắn sẽ không bao giờ thực hiện tra cứu cơ sở dữ liệu khác trong khi ràng buộc, bạn không bao giờ nên truy cập cơ sở dữ liệu trong vòng lặp nhưng miễn là dữ liệu bạn có ràng buộc có thứ gì đó bạn có thể kiểm tra để quyết định xem bạn có muốn hiển thị hay không nó không có gì sai với lọc trong ItemDataBound. Nó có thể là vấn đề nếu bạn đang làm bất kỳ loại phân trang nào từ đó sẽ làm cho các kích thước trang không phù hợp được hiển thị.

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