Så er det igen tid til at komme ud af byen. Påsken er en god anledning til at finde dit kamera frem og ta' med dotninja'erne ud i Dyrehaven

Torsdag d. 1. april 2010 (Skærtorsdag)

Alle er (som altid) velkomne til at joine med deres ynglings kamera (eller bare et de har lånt), det er ikke en aprilsnar (Aprilsnar vil generelt være bandlyst under hele arrangementet). For de interesserede kan der blive tale om at returnere til Frederiksberg for et måltid mad efter arrangement.

Skriv en kommentar om du kommer og om du vil være interesseret i mad. Mødested/tid aftaler vi nærmere når vi nærmer os.

Extension methods har vist sig yderst bekvemme.  Det mest kendte eksempel er naturligvis det væld af extension methods, man finder i LINQ.  De giver en mere præcis og kort notation.  Jeg synes dog, at det kan tage overhånd, fordi folk har tendens til at bruge extension methods til at “dekorere” typer med metoder, som egentlig ikke hører hjemme på typen.  Når frameworks som Rhino Mocks og testdelen af MVC Contrib bruger extension methods på strenge og andre ret grundlæggende typer, kan jeg acceptere det, fordi brugen af test frameworks er så præcist afgrænset.  Men når folk f.eks. begynder at putte extension methods for query string parsing og andet godt på alle strenge i et projekt, mener jeg, at man er gået over grænsen.  Man skal stadig følge OO-reglerne for godt design af en type.

Min egen brug af extension methods har derfor været yderst begrænset.  Jeg har dog defineret to meget nyttige extension methods til WPF typen DependencyObject: GetChild og GetParent.

Metoderne kan benyttes til rekursivt at vandre op eller ned i det visuelle træ for et DependencyObject.  De returnerer det første objekt, de støder på i træet, som er af den type, der er angivet som typeparameter til metoden. 

Koden ser ud som følger.  GetChild har jeg tyvstjålet fra et sted på nettet, hvor man kan finde et utal af nærmest identiske implementationer af metoden.

public static class VisualHelpers
{
    public static T GetChild<T>(this DependencyObject referenceVisual) where T : DependencyObject
    {
        DependencyObject child = null;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(referenceVisual); i++)
        {
            child = VisualTreeHelper.GetChild(referenceVisual, i) as DependencyObject;
            if (child != null && child is T)
            {
                break;
            }

            child = GetChild<T>(child);
            if (child != null && child is T)
            {
                break;
            }
        }
        return child as T;
    }

    public static T GetParent<T>(this DependencyObject referenceVisual) where T : DependencyObject
    {
        if (referenceVisual == null)
            return null;
        if (referenceVisual is T)
            return referenceVisual as T;
        var parent = VisualTreeHelper.GetParent(referenceVisual);
        return parent.GetParent<T>();
    }
}

Så hvad kan man bruge metoderne til?  F.eks. kan man bruge GetChild til at style textbox-delen af en combobox.  Det er der nemlig ikke mulighed for “out-of-the-box”.  Det kan gøres ved at nedarve fra ComboBox og lave en override af OnApplyTemplate.  I OnApplyTemplate benyttes GetChild til at finde combobox’ens ContentPresenter og ændre dens ContentTemplate:

public class ComboBoxEx : ComboBox
{
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        var selectionBoxHost = GetChild<ContentPresenter>(this);
        if (selectionBoxHost != null)
        {
            selectionBoxHost.ContentTemplate = ...;
        }
    }

}