Jak naprogramovat multibarevnou listu pro jakekoliv rozliseni

Dnes jsem si dal trochu pauzu od toho predelavani starsich Windows Forms programu na WPF, protoze me to ukrutne nebavilo se prodirat kody, o kterych jsem nevedel proc jsem je kdysi tak naprogramoval a premyslel jsem jak trochu ozivit ten svuj web.

Napadlo me ze bych mohl udelat barevnou listu a tu vlozit na kazdou stranku nekde. Naprogramovat cele toto mi trvalo asi 4h.

Prvne co jsem udelal bylo ze jsem si to promyslel a dosel jsem k zaveru, ze by byla hloupost abych tuto listu generoval pro kazdou stranku zvlast a proto jsem se rozhodl, ze jednu barevnou listu budou sdilet vsechny rozliseni.

Pak jsem zacal programovat. Zacal jsem s tridou GeneralHelper. Nejtezsi bylo naprogramovat metodu CalculatePercentOfColorBars, ktera jednorazove pri spusteni webu vypocte podle parametru ktere ji predate sirku v % pro jednotlive barvy a samozrejme se zde priradi kazdemu divu unikatni barva.

U me to sice muze vypadat ze to jsou stejne barvy na pohled, ale staci si je dat pod kapatko a zjistite ze i kdyz se lisi treba jen o “1” tak se lisi. A samozrejme tu je jeste pole colorsColorBar, ktere obsahuje tolik barev, kolik maximalne zadate jako druhy argument metode .

Nezapomente, ze kazda barva tam muze byt jen jednou!

GeneralHelper.cs

static string[] colorsColorBar = new string[] { "#3FB1F0",
...
};
/// <summary>
/// V klici bude rozliseni pro ktere se vztahuje, v hodnote pak pole s cisly, ktere budou vyjadrovat % z dostupne sirky ktere barva zabere
/// </summary>
public static Dictionary<short, byte[]=""> percentOfCountBars = new Dictionary<short, byte[]="">();
/// <summary>
/// V klici bude rozliseni, v hodnote pak barvy ke poli, ktere je na stejnem klici jako zde barvy v slovniku percentOfCountBars
/// </summary>
public static Dictionary<short, List=""></short,><string>> colorsOfBars = new Dictionary<short, List=""></short,><string>>();
    public static void CalculatePercentOfColorBars(short width, int pocet)
    {
    List<string> barvyFinal = new List<string>(pocet);
    List<string> colors = new List<string>(colorsColorBar);
    byte percent = 100;
    byte percent2 = 0;
    int pocet2 = pocet;
    pocet2--;
    byte[] b = new byte[pocet];
    byte i = 1;
    for (; i < 10; i++)
    {
        b[i - 1] = i;
        int indexBarvy = RandomHelper.RandomInt2(0, colors.Count);
        barvyFinal.Add(colors[indexBarvy]);
        colors.RemoveAt(indexBarvy);
        pocet--;
        percent2 += i;
        percent -= i;
    }
    //
    while (percent > 0 && pocet != 0)
    {
        if (percent == 2)
        {
            break;
        }
        byte r = RandomHelper.RandomByte2(1, percent > 9 ? 9 : percent);
        if (r > percent)
        {
            continue;
        }
        b[i - 1] = r;
        int indexBarvy = RandomHelper.RandomInt2(0, colors.Count);
        barvyFinal.Add(colors[indexBarvy]);
        colors.RemoveAt(indexBarvy);
        pocet--;
        percent2 += r;
        percent -= r;
        if (percent < 0)
        {
            break;
        }
        i++;
        if (percent < 10 && percent != 0)
        {
            for (int i2 = 1; i2 < percent + 1; i2++)
            {
                int dex = i - 1;
                if (dex > pocet2)
                {
                    break;
                }
                b[dex] = 1;
                indexBarvy = RandomHelper.RandomInt2(0, colors.Count);
                barvyFinal.Add(colors[indexBarvy]);
                colors.RemoveAt(indexBarvy);
                pocet--;
                if (pocet == 0)
                {
                    break;
                }
                percent2 += 1;
                percent -= 1;
                if (percent < 0)
                {
                    break;
                }
                i++;
            }
        }
    }
    //-Zaverecna korekce
    if (percent2 < 100)
    {
        i++;
        int pomer = 100 - percent2;
        if (b.Length == i + 1)
        {
            b[i] = (byte)pomer;
            int indexBarvy = RandomHelper.RandomInt2(0, colors.Count);
            barvyFinal.Add(colors[indexBarvy]);
        }
        else
        {
            b[0] += (byte)pomer;
        }
    }
    int nt = 0;
    for (int i3 = 0; i3 < b.Length; i3++)
    {
        nt += b[i3];
    }
    if (nt > 100)
    {
        int pomer = nt - 100;
        b[8] -= (byte)pomer;
    }
    byte[] b2 = null;
    int b2l = barvyFinal.Count;
    if (b2l == b.Length)
    {
        b2 = b;
    }
    else
    {
        b2 = new byte[b2l];
        for (int y = 0; y < b2l; y++)
        {
            b2[y] = b[y];
        }
    }
    b2 = CA.JumbleUp<byte>(b2);
    percentOfCountBars.Add(width, b2);
    colorsOfBars.Add(width, barvyFinal);
}

Druhe misto kde musite neco dospat je Global.asax. Ten je vzdy v rootu vaseho weboveho projektu – jen tam se bude spravne spoustet pri inicializaci startu vasi webove aplikace.

Global.asax(metoda Application_Start)

GeneralHelper.CalculatePercentOfColorBars(800, 25);
GeneralHelper.CalculatePercentOfColorBars(840, 30);
//-short.MaxValue se bude pouzivat pokud chci umistit MultiColorLine na celou sirku stranky
GeneralHelper.CalculatePercentOfColorBars(short.MaxValue, 36);

Dalsi mistem kde musite neco naprogramovat je trida MultiColorLine. Tato trida zodpovida za vygenerovani odpovidajiciho HTML obsahu s barevnou listou. Tridu HtmlGenerator vam tu davat nebudu, odpovidajici metody si zvladnete jiste naprogramovat sami:

MultiColorLine.cs

using System.Collections.Generic;
public class MultiColorLine
{
    public static string GetHtml(short width)
    {
        byte[] sirky = GeneralHelper.
        percentOfCountBars[width];
        List<string> colors = GeneralHelper.colorsOfBars[width];
        HtmlGenerator hg = new HtmlGenerator();
        int bl = sirky.Length - 1;
        for (int i = 0; i < bl; i++)
        {
            hg.WriteTagWith2Attrs("div", "class", "partColorBar", "style", "width:" + sirky[i] + "%;background-color:" + colors[i]);
            hg.TerminateTag("div");
        }
        hg.WriteTagWith2Attrs("div", "class", "partColorBar", "style", "width:" + sirky[bl] + "%;background-color:" + colors[bl] + ";float:right;");
        hg.TerminateTag("div");
        return hg.ToString();
    }
} </string>

Predposledni misto je pak samotna (Master)Page ve ktere zavolate . Ve strance na odpovidajici misto vlozte tento div a popripadne nastylujte podle vlastniho uvazeni:

Neco.Master

<div id="divBarevnaLista" runat="server"></div>

Ve code behindu pak dejte nasledujici kod(pouze si upravte jak chcete mit listu sirokou v 1. argumentu), ktery vytvori HTML kod a vlozi vam jej jako vnitrek divu.

Neco.Master.cs

divBarevnaLista.InnerHtml = MultiColorLine.GetHtml(800);

Ve strance, pripadne externim CSS pak musite mit i toto CSS:

Neco.css

.partColorBar {
	height: 5px;
	max-height: 5px;
	min-height: 5px;
	display: inline-block;
	padding: 0;
	margin: 0;
	float: left;
}

Poslednim kodem ktery vam tu dam jsou ty dalsi metody ktere jsem volal, abyste nemuseli tapat, jak je implementovat:

internal static T[] JumbleUp<T>(T[] b)
{
    int bl = b.Length;
    for (int i = 0; i < bl; ++i)
    {
        int index1 = (RandomHelper.RandomInt() % bl);
        int index2 = (RandomHelper.RandomInt() % bl);
        T temp = b[index1];
        b[index1] = b[index2];
        b[index2] = temp;
    }
    return b;
    }
    public static class RandomHelper
    {
    static Random rnd = new Random();
    internal static int RandomInt2(int od, int to)
    {
        return rnd.Next(od, to);
    }
    internal static byte RandomByte2(int od, int to)
    {
        return (byte)rnd.Next(od, to);
    }
} 

Vysledek?


Default.aspx s barevnou listou


BibleServer s barevnou listou

Leave a Reply