Zmiany, zmiany, zmiany

Z początkiem roku zmieniło się dużo w moim życiu programistycznym i nie tylko:

  • zmieniłam miejsce zamieszkania wracając tym samym z Warszawy do Krakowa
  • zmieniłam miejsce pracy z MRM Worldwide na Making Waves
  • zmieniłam… nie akurat już nie miejsce, ale technologię w jakiej na co dzień będę pracować z PHP na ASP.NET i C#, co sprawia że spełnia się mój zawodowy plan o ciągłym rozwoju:)

Kiedy mamy problem z CSSami…

Każdy z nas czasem patrzy na swój plik css oraz na strukturę htmla swojej strony i zastanawia się dlaczego ten tekst jest zielony, chociaż w cssie wyraźnie widnieje, że ma być czerwony i do tego podkreślony… W prostych cssach łatwo błąd znaleźć i naprawić. W bardziej skomplikowanych może nam to przysporzyć sporo straconego czasu i nerwów;)
Niedawno znalazłam coś, co może sprawić, że już nigdy więcej nie będę się zastanawiać „dlaczego to nie działa”;) Co prawda takich sytuacji nie miewam wiele, ale ich całkowite wyeliminowanie nie zaszkodzi:)
Lekarstwem na te problemy ma być tzw. CSS Specificity czyli jeśli upieramy się przy tłumaczeniu na język ojczysty – Specyficzność CSS, a dokładniej sposób w jaki reguły zapisane przez nas w cssach są realizowane przez przeglądarki.
Pierwsza rzecz, na której wszystko się opiera, to fakt iż poszczególne selektory mają przyporządkowane pewne wagi. Wagi te przedstawiają się następująco:

  • największą wagę (1000) mają selektory znajdujące się jako atrybut we właściwości style danego elementu, np.:
    <span style="color: green;">Zielony tekst</span>
  • kolejne (waga 100) są identyfikatory elementów, np.:
    #kontener
    {
        background-color:yellow;
    }
  • następne w kolejce (waga 10) są nazwy klas, atrybutów i pseudoklas, np.
    .zielona_klasa
    {
        color: green;
    }
    a:link
    {
        text-decoration:underline;
    }
  • Ostatnie, najmniej liczące się (dosłownie;) – waga 1) to elementy i pseudoelementy, np.:
    <img alt="" />
    :after

Dla lepszego zrozumienia przejrzyjmy parę przykładów obliczania specificity:

  1. #left_column div
    {
        border: solid 1px;
    }

    Mamy tutaj jeden identyfikator (100) i jeden element (1), co w sumie (100+1) daje nam specificity na poziomie 101.

  2. Weźmy przykład cssów które nieraz potrafią nieźle namieszać. Mianowicie jeśli z jakiś przyczyn część definicji mamy w zewnętrznym pliku css, a część inline w kodzie HTML. Przykładowo, w cssie mamy coś takiego:
    #menu
    {
       border:solid 1px;
       background-color: green;
    }

    natomiast w pliku html coś takiego:

    <div id="menu" style="background-color: blue">[tutaj menu bedzie]</div>

    Mamy więc 1000 za styl inline oraz 100 za identyfikator. Co w sumie daje 1100.

W ostatnim przykładzie nasuwa się nam pewna kwestia. Mianowicie jakiego koloru w efekcie będzie tło tego menu? Niebieskie czy zielone?
Odpowiedź brzmi niebieskie. Powodem tego jest kolejna rzecz odgrywająca ważną rolę w specificity – jedne elementy są ważniejsze niż inne. I tak kiedy mamy style zdefiniowane inline, nadpisują one wszystkie inne poprzedzające je (czy to zawarte w identyfikatorach, czy klasach czy elementach). W kwestii dalszej hierarchii: style zdefiniowane w identyfikatorach są ważniejsze niż style zdefiniowane w klasach, a te z kolei są ważniejsze niż te zdefiniowane w elementach. Oto prosta ilustracja:

/*** domyślnie tło dokumentu będzie białe a wszystkie czcionki ustawiamy na Verdanę w rozmiarze 10px ***/
body
{
    font-size: 10px;
    font-family: Verdana;
    background-color: #FFF;
}
/*** jednak chcielibyśmy, żeby header naszej strony był wyróżniony odpowiednią czcionką ***/
#h1
{
    font-size: 19px;
    font-weight: bold;
}
/*** niektóre elementy będą dodatkowo pisane kursywą ***/
.italic
{
    font-weight: normal;
    font-style: italic;
}
<h1>Tekst headera</h1>
<div class="italic" style="background-color: yellow">Jakiś tekst pisany kursywą</div></h1>

Co się z tym stanie?
Dokument wstępnie miał ustawione tło na białe, czcionkę na Verdanę w rozmiarze 10px. Jednak już na wstępie, gdy pojawia się header (h1) zmienia się rozmiar czcionki oraz zostaje ona pogrubiona. Tak więc style identyfikatora nadpisały style elementu. Z kolei div znajdujący się w headerze ma przypisany styl inline, który zmienia tło tegoż elementu nadpisując kolejną właściwość ustawioną w body. Ktoś jeszcze mógłby się zastanawiać… przecież Verdana 10 i białe tło zostały ustawiona na elemencie body, a nie div. Przypominam o dziedziczeniu:) W końcu to cascading style sheets. Jeśli nie ustawimy inaczej to styl przypisany naszemu divowi jest identyczny jak ten, który został nadany body, ponieważ body jest przodkiem diva;)
Parę rzeczy o których warto pamiętać jeśli chodzi o specificity:

  • jeśli dany element definiują różne grupy selektorów to ta, która ma większą specificity zadziała
  • jeśli te grupy selektorów mają tą samą specificity, wówczas zadziała ta która została zdefiniowana jako ostatnia

I jeszcze link do kalkulatora specificity – Kalkulator

Najprostszy sposób odczytywania danych z GET’a w ASP.NET 2.0 i C#

Najprostszy oczywiście nie oznacza najlepszy. Można go użyć, jeśli z jakiś przyczyn nie chcemy tworzyć kodu C# w osobnym pliku i mamy coś megaprostego do zrobienia.
Załóżmy więc, że mamy taki oto prościutki formularz:

1
2
3
4
5
<form action="index.aspx">
    <input name="login" type="text">
    <input name="password" type="password">
    <input type="submit" name="Zaloguj" value="Zaloguj">
</form>

Fajnie by było, gdyby po błędnym zalogowaniu formularz nadal pamiętał login jaki wpisaliśmy w pole login.
Zmienimy więc odpowiednio linijkę numer 2:

2
3
<input name="login" type="text"
value="<%=HttpUtility.HtmlEncode(Request.QueryString["login"])%>">

W ten sposób wartość pola login będzie zawsze miała taką wartość jaka została wpisana przed wysłaniem formularza.
Generalnie Request.QueryString[„login”] przechowuje wartość pola „login”.

Pomoż Firefoxowi pobić rekord Guinnessa w pobieraniu:)

Z racji zbliżającej się premiery Firefox 3, twórcy postawili sobie za cel pobicie rekordu Guinnessa w ilości pobrań aplikacji. Do propagowania akcji może przyłączyć się każdy. Szczegóły akcji na http://www.spereadfirefox.com

Download Day - Polish

Snippety w Visual Studio – C#

Jest to jedna z moich ulubionych funkcjonalności z cyklu „ułatwiających życie” w Visual Studio:)
Snippety umożliwiają łatwe wstawienie kawałka „szablonowego” kodu – np. if…else, for, switch itd.
Dostępne snippety można przejrzeć wybierając z menu Tools->Code Snippets Manager. Można w tym miejscu tworzyć również swoje własne snippety.
Wstawić snippet do swojego kodu można poprzez wpisanie przypisanego do niego słowa i naciśnięcie tabulatora (szerzej o tym sposobie będzie dalej, ponieważ uważam go za zdecydowanie wygodniejszy) lub poprzez wybranie z menu Edit->InteliSense->Insert Snippet (kombinacja klawiszy: Ctrl+K, X), następnie wybranie Visual C# oraz wybranie żądanego snippetu.

Najfajniejsze i najprzydatniejsze wg mnie po kolei :
Cel: utworzenie dyrektywy kompilacji warunkowej (nie będę wchodzić w szczegóły działania poszczególnych kawałków kodu, ponieważ nie to jest przedmiotem tej notki;))
Słowo, które wpisujemy: #if (i naciskamy tab)
Otrzymujemy:

#if true
 
#endif

(kursor znajduje się na słowie true, dzięki czemu łatwo możemy zmienić je na takie jakiego potrzebujemy)

Cel: utworzenie dyrektywy pozwalającej na ukrywanie (zwijanie) kodu w edytorze
Słowo, które wpisujemy: #region
Otrzymujemy:

#region MyRegion
 
#endregion

(kursor znajduje się na słowie MyRegion, umożliwiając natychmiastową zmianę nazwy regionu)

Cel: utworzenie szkieletu klasy
Słowo, które wpisujemy: class
Otrzymujemy:

class MyClass
{
 
}

(kursor znajduje się na słowie MyClass)

Cel: utworzenie wywołania funkcji Console.Writeline
Słowo, które wpisujemy: cw
Otrzymujemy:

Console.WriteLine();

(kursor znajduje się w nawiasie celem wpisania tam tekstu jaki ma zostać wyświetlony)

Cel: utworzenie szkieletu pętli do…while
Słowo, które wpisujemy: do
Otrzymujemy:

do
{
 
} while (true);

(kursor znajduje się na słowie true – wpisujemy treść warunku)

Cel: utworzenie szkieletu instrukcji else
Słowo, które wpisujemy: else
Otrzymujemy:

else
{
 
}

(kursor znajduje się między nawiasami)

Cel: utworzenie szkieletu pętli for
Słowo, które wpisujemy: for
Otrzymujemy:

for (int i = 0; i < length; i++)
{
 
}

(kursor znajduje się na zmiennej i w pierwszym wyrażeniu, umożliwiając jej zmianę – jeśli w tym miejscu zmienimy i, to zmieni się ono też w pozostałych wyrażeniach; naciśnięcie tabulatora spowoduje przejście do zmiennej length w drugim wyrażeniu i umożliwi jej zmianę)

Cel: utworzenie szkieletu pętli foreach
Słowo, które wpisujemy: foreach
Otrzymujemy:

foreach (object var in collection_to_loop)
{
 
}

(kursor znajduje się na słowie object umożliwiając wyedytowanie kolejny parametrów – var, collection_to_loop)

Cel: utworzenie szkieletu pętli forr
Słowo, które wpisujemy: forr
Otrzymujemy:

for (int i = length - 1; i >= 0; i--)
{
 
}

(kursor znajduje się na zmiennej i w pierwszym wyrażeniu – działa podobnie jak snippet dla for, ale iteracja idzie w drugą stronę)

Cel: utworzenie szkieletu pętli if
Słowo, które wpisujemy: if
Otrzymujemy:

if (true)
{
 
}

(kursor znajduje się na słowie true)

Cel: utworzenie wywołania funkcji MessageBox.Show();
Słowo, które wpisujemy: mbox
Otrzymujemy:

MessageBox.Show("Test");

(kursor znajduje się na słowie Test)

Cel: utworzenie szkieletu instrukcji definiującej przestrzeń nazw
Słowo, które wpisujemy: namespace
Otrzymujemy:

namespace MyNamespace
{
 
}

(kursor znajduje się na słowie MyNamespace)

Cel: utworzenie szkieletu instrukcji switch
Słowo, które wpisujemy: switch
Otrzymujemy:

switch (switch_on)
{
    default:
}

(kursor znajduje się na słowie switch_on)

Cel: utworzenie szkieletu instrukcji try…catch
Słowo, które wpisujemy: try
Otrzymujemy:

try
{
 
}
catch (Exception)
{
    throw;
}

(kursor znajduje się na słowie Exception)

Cel: utworzenie szkieletu instrukcji while
Słowo, które wpisujemy: while
Otrzymujemy:

while (true)
{
 
}

(kursor znajduje się na słowie true)