2016-04-13 9 views
2

Çok sayıda onay kutum var, şu anda her sütunu içeren bir div ile 3 sütun halinde koymak istiyorum.Liste verisini traş kullanarak birçok taneye bölmek için zarif bir yol

Ancak, oldukça kaprisliyim ve onları yarın 10 veya 20 sütun halinde koymak isteyebilirim, satırları veya başka türdeki bir div olarak döndürmek isteyebilirim.

3 sütun için bir örnek: Öncelikle bu kullanarak 3 süre yapmaya çalıştım

<div class="column-1"> 
    <input type="checkbox" id="foo-1">Checkbox # 1 
    <input type="checkbox" id="foo-2">Checkbox # 2 
    <input type="checkbox" id="foo-3">Checkbox # 3 
</div> 
<div class="column-2"> 
    <input type="checkbox" id="foo-4">Checkbox # 4 
    <input type="checkbox" id="foo-5">Checkbox # 5 
    <input type="checkbox" id="foo-6">Checkbox # 6 
</div> 
<div class="column-3"> 
    <input type="checkbox" id="foo-7">Checkbox # 7 
    <input type="checkbox" id="foo-8">Checkbox # 8 
    <input type="checkbox" id="foo-9">Checkbox # 9 
</div> 

aşağıda döngüler: Bu iyi çalışır, ama çok çirkin olur

@{ 
    int i = 0; 
    IEnumerable<foo> bar = new List<foo>(){foo1,foo2,foo3,foo4,foo5,foo6}; 
} 
    <div id="column-1"> 
     while (i < bar.Count()/3) 
     { 
     baz = bar.ElementAt(i); 
     <input type="checkbox" id="[email protected]" checked='@baz.CheckIt' />@baz.DisplayText 
     i++; 
     } 
    </div> 
    <div id="column-2"> 
     @while (i < bar.Count() * 2/3) 
     { 
     baz = bar.ElementAt(i); 
     <input type="checkbox" id="[email protected]" checked='@baz.CheckIt' />@baz.DisplayText 
     i++; 
     } 
    </div> 
    <div id="column-3"> 
     @while (i < bar.Count()) 
     { 
     baz = bar.ElementAt(i); 
     <input type="checkbox" id="[email protected]" checked='@baz.CheckIt' />@baz.DisplayText 
     i++; 
     } 
    </div> 

kullanmak istediğim eğer 3'ten fazla sütun. Zaten oldukça çirkin bir şekilde. Ayrıca, sütun sayısının kolayca değiştirilmesine izin vermez. Ayrıca, her biri farklı bir değere (sırasıyla 0,1,2) başlayan ve i 3 sayısını artıran döngüler için değiştirilebilir, ancak bu hala 3 döngülerdir.

Ben de bu yüzden (pseudocode) gibi bazı modül operatörünü kullanarak tek bir döngü içinde bunu yapmak için çalıştı: çok daha özlü ve okunabilir Bence olduğunu

i = 0 
foreach(checkbox in list) 
{ 
    if(i % numberOfColumns == 0) 
    { 
     createNewRow() 
    } 
    placeCheckBox() 
    i++ 
} 

. Ancak bu, amacım için iyi bir hizmet sunmayan çok sayıda satır divs verir. Ayrıca aslında kutunun içinde olmak için onay kutusunu alma sorunu var. Yukarıdaki iki çözüm, satırlardan ziyade sütunlar oluşturmak için birleştirilebilirdi, bu daha iyi görünüyor ama yine de ikinci çözümle aynı sorunlara sahip.

Bunu yapmak için çok daha basit ve daha iyi bir yol olmalı, sütunların sayısını kodlamak zorunda kalmadan, hiç kimsenin bu temelden 20'sini yazmak istemediğinden.

Ayrıca, bir listedeki her öğe için html etiketleri oluşturmanın genişletilebilir ve özlü bir yolu var mıdır? Eğer öyleyse ne var?

cevap

2

(belki netlik için her iki varlık while olarak değiştirin olmalıdır).

Bu, listeyi sırayla ve sırayla sıralı olarak kaydırır; her seferinde numberOfColumns kesirine ulaştığında durur. Daha sonra yeni bir sütun oluşturur ve öğelerin bir sonraki bölümünü elde etmek için kesiri artırır.

@{ 
    int numberOfColumns = 3; 
    int currentItemIndex = 0; 
    for (int currentColumnIndex = 1; currentColumnIndex <= numberOfColumns; currentColumnIndex++) 
    { 
     //Create a new column 
     <div id="[email protected]"> 
      //Loop populate column with items 
      @while (currentItemIndex < bar.Count() * currentColumnIndex/numberOfColumns) 
      { 
       baz = bar.ElementAt(currentItemIndex); 
       //Add each item 
       <input type="checkbox" id="[email protected]" checked='@baz.CheckIt' />@baz.DisplayText 
       currentItemIndex++; 
      } 
     </div> 
    } 

} 

iki sütun için bir adım-adım örnek:

Eğer dış döngü iki kere çalıştıracaktır numberOfColumns = 2 yaptıysanız. İlk uygulamada, iç döngü currentItemIndexbar.Count() * 1/2'a veya bar.Count()'un yarısına kadar olan ilk sütundaki öğelerinizin yarısı kadar gider.Daha sonra, bar.Count() için iç döngü için maksimum sayacı artırarak, dış döngünün bir sonraki aşamasına kadar yineler, çünkü sayaç hala bar.Count()'un yarısına ayarlanır, bu da ikinci sütundaki öğelerin ikinci yarısını yerleştirir. İşte bu kadar!

3

Yorgun olduğum için yöntem adlarıyla biraz tembelleşiyorum. Bu, bir IEnumerable of T'yi IE'nin IE'den ayırt edilemez bir parçasına bölecektir (Belki de sadece dizileri geri göndermeliydim.) Eğer 100 verirseniz ve üçlü gruplara ayırırsanız, 34 liste alırsınız. İlk 33 listelerde 3 eleman olacak ve sonuncusu bir olacak.

public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int itemsPerSet) 
{ 
    var sourceArray = source as T[] ?? source.ToArray(); 
    var result = new List<IEnumerable<T>>(); 
    for (var index = 0; index < sourceArray.Length; index += itemsPerSet) 
    { 
     result.Add(sourceArray.Skip(index).Take(itemsPerSet)); 
    } 
    return result; 
} 

oldukça basit iç içe döngüler kullanarak çözüldü Birim testi

[TestMethod] 
public void splits_100_by_3_into_34() 
{ 
    var values = Enumerable.Range(1, 100); 
    var splitValues = values.Split(3); 
    Assert.AreEqual(splitValues.Count(), 34); 
    Assert.IsTrue(splitValues.ElementAt(0).SequenceEqual(Enumerable.Range(1, 3))); 
    Assert.AreEqual(splitValues.ElementAt(33).Count(), 1); 
    Assert.AreEqual(splitValues.ElementAt(33).ElementAt(0), 100); 
} 
İlgili konular