Malé a veľké písmena v univerzálnej aplikácii

V univerzálnej aplikácii pre Windows a Windows Phone som sa snažil dať čo najviac XAML kódu do spoločných views a meniť vzhľad pre jednotlivé platformy len cez štýly. Avšak narazil som na problém s malými a veľkými písmenami pri nadpise stránky (obrazovky). Zatiaľ čo pre Windows sa pre nadpisy používa veľké začiatočné písmeno a ostatné malé, pre Windows Phone má nadpis menší font, ale na zvýraznenie sú všetky písmená veľké.

Titulok vo Windows

Titulok vo Windows aplikácii

Titulok vo Windows Phone

Titulok vo Windows Phone aplikácii 

Vo WPF na to slúži vlastnosť CharacterCasing, ktorú stačí nastaviť cez štýl. Avšak vo WinRT táto vlastnosť chýba :( Druhá možnosť je použiť IValueConverter. Takže som si spravil CharacterCasingConverter, ktorý skonvertuje text na veľké alebo malé písmena podľa parametra.

public class CharacterCasingConverter : IValueConverter

{

    public object Convert(object value, Type targetType, object parameter, string language)

    {

        if (targetType != typeof(string))

        {

            throw new NotSupportedException();

        }


        if (value == null)

        {

            return null;

        }


        var stringValue = System.Convert.ToString(value);

        if (stringValue == null)

        {

            return null;

        }


        var stringParameter = System.Convert.ToString(parameter);

        if (string.Equals(stringParameter, "lower", StringComparison.OrdinalIgnoreCase))

        {

            stringValue = stringValue.ToLower();

        }

        else if (string.Equals(stringParameter, "upper", StringComparison.OrdinalIgnoreCase))

        {

            stringValue = stringValue.ToUpper();

        }


        return stringValue;

    }

 

    public object ConvertBack(object value, Type targetType, object parameter, string language)

    {

        if (targetType != typeof(string))

        {

            throw new NotSupportedException();

        }


        if (value == null)

        {

            return null;

        }


        return System.Convert.ToString(value);

    }

}

Teraz stačí tento converter dať do Application Resources.

    <Application.Resources>

        <ResourceDictionary>

            <ResourceDictionary.MergedDictionaries>

                <ResourceDictionary Source="Resources.xaml" />

               

                <ResourceDictionary>

                    <converters:VisibilityConverter x:Key="VisibilityConverter" />

                    <converters:CharacterCasingConverter x:Key="CharacterCasingConverter" />

                </ResourceDictionary>

            </ResourceDictionary.MergedDictionaries>

        </ResourceDictionary>

    </Application.Resources>

A do Resource súboru pre špecifickú platformu stačí pridať string, s príslušným kľúčom, že či chceme veľké alebo malé písmena. Tento string sa potom použije ako parameter pre converter. Lenže počkať. WinRT nepodporuje stringy v Resourcoch. Takže si musím vyrobiť niečo, čo sa dá jednoducho skonvertovať na string. Ako ste si všimli, tak CharacterCasingConverter s tým ráta. Tak som si vytvoril enum a class CharacterCasingParamer, ktorý sa použije ako parameter pre converter.

public enum CharacterCasing

{

    None,

    Upper,

    Lower

}


public class CharacterCasingParameter

{

    public CharacterCasing Casing { get; set; }


    public override string ToString()

    {

        return this.Casing.ToString();

    }

}

A teraz stačí tento objekt pridať do Resource súboru pre danú platformu.

<Style x:Key="PageHeaderTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource TitleTextBlockStyle}" />

<converters:CharacterCasingParameter x:Key="PageHeaderCharacterCase" Casing="Upper" />

A nakoniec to všetko treba použiť v XAML pre view stránky.

<TextBlock Grid.Column="1" x:Uid="/Resources/AddCityTitle" Style="{StaticResource PageHeaderTextBlockStyle}"

    Text="{Binding Tag, RelativeSource={RelativeSource Self}, Converter={StaticResource CharacterCasingConverter}, ConverterParameter={StaticResource PageHeaderCharacterCase}}"

    IsHitTestVisible="false" TextWrapping="NoWrap" VerticalAlignment="Bottom" />

Všimnite si ešte jeden malý trik. V skutočnosti som nepoužil binding na ViewModel, ale na Tag vlastnosť toho istého TextBlocku. A potom v lokalizačných stringoch som zadefinoval preložený text pre AddCityTitle.Tag.

Komentáre

# liero said:

Ja som taky maniak na to, aby xaml kod viewu bol co najstrucnejsi a najsemantickejsi, preto by som sa snazil ten binding zjednodusit.

1. Namiesto ConverterParameter by som pridal ten enum ako property convertera a vytvoril si pre kazdu hodnotu novy instanciu v resourcoch.

<converters:CharacterCasingConverter x:Key="UpperCasingConverter" Casing="Upper"  />

Thursday, July 31, 2014 9:51 AM
# liero said:

2. Asi by som pouzil T4 template na generovanie C# triedy, ktora by umoznovala pristup k resourcom cez properties, tak ako sme zvyknuty z wpf, alebo asp.net. Jej instanciu by som pridal bud do resourcov, alebo do viewmodelu.

binding b potom vyzeral takto:

Text="{Binding PageHeader, Source={StaticResource Translations}

resp.:

Text="{Binding Translations.PageHeader}"

Thursday, July 31, 2014 9:58 AM
# duracellko said:

@liero.. dobry napad.. myslim oba

Thursday, July 31, 2014 11:52 AM
Prihlásiť | Registrovať | Pomoc