XAML.cz Magazín moderních technologií založených na XAML

WPF - Štetce - SolidColorBrush

Napsáno pro WPF od Martin Bodocky [13.04.2010]

Dneska otvoríme novú sériu člankov o štetcoch vo WPF, budem sa Vám snažit postupne predstaviť základné triedy na prácu s štetcami a technológiami s nimi spojenými. Hneď na začiatku si musíme položiť  otázku “na čo sú vlastne štece dobré ?”. Určite ich využijete pri “skrášlení” vašich užívateľských rozhraní, tvorbe animácii, validaćii, či zvýraznení dôležitých údajov. Použitie nájdete všade tam kde budete grafické objekty používať.

Dneska si ukážeme, ako pracovať z triedou SolidColorBrush. Na začiatku si ukážeme zápis v jazyku C# a v XAML jazyku.

Ako v C# ?

using System;
using System.Windows;
using System.Windows.Media;
namespace SolidColor
{
    public class Program : Window 
    { 
        [STAThread]         
        public static void Main(string[] args) 
        { 
            new Application().Run(new Program()); 
        } 
        public Program() 
        { 
            Background = new SolidColorBrush(Colors.DarkMagenta); 
        } 
    }
}

Jedná sa o jednoduchú farbu, ktorej môžeme nastaviť farebné vlastnosti všetkých grafických objektov vo WPF. Ale nemusíme sa obmedzovať na výčtový typ Colors. Môžeme ju poskládať pomocou hodnôt červenej, zelenej a modrej:

Background = new SolidColorBrush(Color.FromRgb(126, 169, 225));

Pre grafických obľúbencov môžeme aj takto:

Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF7EA9E1"));

Ako v Xaml ?

Ako uvidíte, v xaml jazyku to je rovnaké a úplne jednoduché.

<Window x:Class="WPFSolidColorBrush.SolidColor"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="SolidColor" Height="300" Width="300">
    <Window.Background>
        <SolidColorBrush Color="Crimson"/>
    </Window.Background>
</Window>

A presne tak sme si to ukázali v predchádzajúcom odstavci, tak si to ukážeme v XAMLu. Skladanie pomocou hodnôt RGB:

<SolidColorBrush>
  <SolidColorBrush.Color>
    <Color R="126" G="169" B="225"/>
  </SolidColorBrush.Color>
</SolidColorBrush>

Ale jednoduchšie to bude pre grafikov:

<SolidColorBrush Color="#FF7EA9E1"/>

Úkažková aplikácia

Chcem vám, čo najviac osvojiť túto triedu. Tak som pre vás pripravil aplikáciu , kde si budete môcť sami zostaviť farbu, ktorú budete potrebovať. A ešte si to vyskúšať na objekte tlačítka. Celá aplikácia sa bude skladať zo štyroch zdrojových súborov. Základným je súbor SolidColor.xaml z definíciou triedy, na ktorý bude pripojený SolidColor.xaml.cs. Ďaľšie dva súbory obsahujú konvertory, ktoré si predstavíme ako prvé. Musíme vedieť na čo nám sú dobré. Prvý konvertor vykonáva konverziu medzi typom double a byte :

[ValueConversion(typeof(double), typeof(byte))]
public class DoubleToByteConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is double)
        {
            return (byte)(double)value;
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is byte)
        {
            return (double)value;
        }
        return null;
    }
}

Ako fungujú konvertory sa dozviete v tomto článku, pre nás bude dôležité vedieť iba jeho funkciu. Funkciu prvého konvertova využijeme pri predove parametru Value objektu Slider.  Druhý konvertor nám bude konvertovať tri hodnoty na názov farby:

public class ValuesToColorString : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Color clr = Color.FromRgb((byte)(double)values[0],
            (byte)(double)values[1],
            (byte)(double)values[2]);

        return clr.ToString();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

Tento konvertor priímá tri hodnoty R,G a B hodnôt farby, z ktorých poskláda odpovedajúcu farbu a pošle nám iba univerzálny názov tejto farby.

Teraz si ukážeme kompletný kód XAML tejto aplikácie.

<Window x:Class="SolidColor.SolidColor"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:s="clr-namespace:SolidColor"
        Title="Solid Color" SizeToContent="WidthAndHeight">
    <Grid MinHeight="200" MinWidth="300">
        <Grid.Resources>
            <s:DoubleToByteConverter x:Key="conv"/>
            <s:ValuesToColorString x:Key="convValues"/>
            <Style TargetType="{x:Type Slider}">
                <Setter Property="MinHeight" Value="130"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="Maximum" Value="255"/>
                <Setter Property="Minimum" Value="0"/>
                <Setter Property="Orientation" Value="Vertical"/>
                <Setter Property="Margin" Value="12"/>
            </Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="Margin" Value="10"/>
                <Setter Property="Width" Value="120"/>
                <Setter Property="Height" Value="80"/>
                <Setter Property="Background">
                    <Setter.Value>
                        <SolidColorBrush>
                            <SolidColorBrush.Color>
                                <Color R="0" G="0" B="0" />
                            </SolidColorBrush.Color>
                        </SolidColorBrush>
                    </Setter.Value>
                </Setter>
                <Setter Property="Foreground">
                    <Setter.Value>
                        <SolidColorBrush>
                            <SolidColorBrush.Color>
                                <Color R="255" G="255" B="255" />
                            </SolidColorBrush.Color>
                        </SolidColorBrush>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style TargetType="{x:Type RadioButton}">
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="Margin" Value="5"/>
            </Style>
            <Style TargetType="{x:Type TextBlock}" x:Key="Popis">
                <Setter Property="FontSize" Value="20"/>
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalAlignment" Value="Top"/>
            </Style>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="FontSize" Value="15"/>
                <Setter Property="FontWeight" Value="Bold"/>
                <Setter Property="IsEnabled" Value="False"/>
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalAlignment" Value="Bottom"/>
                <Setter Property="Text" Value="{Binding Path=Value, Converter={StaticResource conv}}"/>
            </Style>
        </Grid.Resources>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150*"/>
                <ColumnDefinition Width="150*"/>
            </Grid.ColumnDefinitions>
            <StackPanel Orientation="Horizontal" Grid.Column="0" >
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="R" Style="{StaticResource Popis}"/>
                    <Slider Name="clrR" ValueChanged="clr_ValueChanged"/>
                    <TextBlock DataContext="{Binding ElementName=clrR}"/>
                </StackPanel>
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="G" Style="{StaticResource Popis}"/>
                    <Slider Name="clrG" ValueChanged="clr_ValueChanged"/>
                    <TextBlock DataContext="{Binding ElementName=clrG}" />
                </StackPanel>
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="B" Style="{StaticResource Popis}"/>
                    <Slider Name="clrB" ValueChanged="clr_ValueChanged" />
                    <TextBlock DataContext="{Binding ElementName=clrB}"/>
                </StackPanel>
            </StackPanel>
            <StackPanel Grid.Column="1" Orientation="Vertical">
                <RadioButton Name="radioFore" Content="Foreground" Checked="radioFore_Checked" />
                <RadioButton Name="radioBack" Content="Background" Checked="radioBack_Checked" />
                <Button Name="btn" Content="Kopírovať" Click="btn_Click" Focusable="False"/>
                <TextBox Name="txtbox"  FontSize="13" VerticalAlignment="Bottom" 
                         HorizontalAlignment="Center">
                    <TextBox.Text>
                        <MultiBinding Converter="{StaticResource convValues}">
                            <Binding ElementName="clrR" Path="Value"/>
                            <Binding ElementName="clrG" Path="Value"/>
                            <Binding ElementName="clrB" Path="Value"/>
                        </MultiBinding>
                    </TextBox.Text>
                </TextBox>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

Naše uživáteľské rozhranie je rozdelené na tri sektory. V prvom sektore, kde sa nachádzajú tri objekty triedy Slider, podľa ktorých budeme nastavovať hodnoty farby RGB. Všetky objekty typu Slider majú nastavený štýl, ktorý definuje ich vlastnosti, viac o nich sa dozviete tu. Pri zmene hodnoty akého koľvek objektu typu Slider zavoláme funkciu clr_ValueChanged, exekúciu vysvetlíme neskôr. V druhom sektore, ktorý sa nachádza v pravo hore rozhrania, sú dva objekty typu RadioButtonu, kde nastavujeme či budeme meniť hodnotu pozadia alebo popredia nášho tlačítka. V treťom sektore sa nachádza naše tlačítko, na ktoré aplikujeme zmeny farieb RGB. Pod naším tlačítkom sa ešte nachádza TextBox, ktorý nám ukáže univerzálny názov danej farby a tento názov získame vďaka našemu druhému konvertoru. Ten poskladá pomocou Bindingu od každého objektu Slider, hodnotu parametra Value. Teraz si ukážeme ako ošetriť události, ktoré sme v našom XAML súbore naznačili.

public partial class SolidColor : Window
{
    [STAThread]
    public static void Main()
    {
        new Application().Run(new SolidColor());
    }
    public SolidColor()
    {
        InitializeComponent();
        radioFore.IsChecked = true;
        radioBack.IsChecked = true;
    }
    private Color GetColor()
    {
        double r = clrR.Value;
        double g = clrG.Value;
        double b = clrB.Value;
        return Color.FromRgb((byte)r, (byte)g, (byte)b);
    }
    private void SetColor(Color clr)
    {
        clrB.Value = clr.B;
        clrG.Value = clr.G;
        clrR.Value = clr.R;
    }
    private void radioFore_Checked(object sender, RoutedEventArgs e)
    {
        SetColor((btn.Foreground as System.Windows.Media.SolidColorBrush).Color);
    }

    private void radioBack_Checked(object sender, RoutedEventArgs e)
    {
        SetColor((btn.Background as System.Windows.Media.SolidColorBrush).Color);
    }
    private void clr_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        if (radioFore.IsChecked.GetValueOrDefault(false))
            btn.Foreground = new System.Windows.Media.SolidColorBrush(GetColor());
        else
            btn.Background = new System.Windows.Media.SolidColorBrush(GetColor());
    }
    private void btn_Click(object sender, RoutedEventArgs e)
    {
        Clipboard.SetText(txtbox.Text);
    }
}

Událosť, ktorá nastane pri zmene hodnoty objektov Slider, najprv overí, aký RadioButton je označený. Podľa toho použije farbu z funkcie GetColor(), ktorá poskladá hodnoty RGB z objektov Slider. Ďaľšia událosť, ktorá nastane pri zmene označenia, vyvolá funkciu SetColor(Color clr) a tá nastaví objekty Slider na hodnoty danej farby. Posledná událosť nad objektom Button nám dá do klipboardu textový názov farby aby sme ju mohli po “namiešaní” niekde použiť.

Týmto príkladom som Vám chcel ukázať a vytvoriť jednoduchú utilitu, ktorá vám určite spríjemní prácu z nastavovaním objektov SolidColorBrush. To bude dnes všetko, zdrojové súbory nájdete tu. Všetky pripomienky a návrhy píšte do komentárov, ďakujem za pozornosť a prajem pekný deň;)

Komentáře

ukládám komentář, vyčkejte prosím..
  1. Buďte první, kdo napíše komentář.

@xamlcz

  • RT @jvanrhyn: XAML, It's a bit like olives. Takes a while to get used to. But once you're used to it. It is actually pretty good. <3 XAML
  • RT @moser_christian: WPF Inspector 0.9.7 is released. It supports .NET 3.5 and 4.0 The project is now open source and available on CodeP ...
  • Jeff Handley oznámil vydání WCF RIA Services v.1.0 SP1 RTM http://bit.ly/gOgckn ke stažení na http://bit.ly/gVAXdK
  • jedna výzva pro Brno. Byl někdo z vás na přednášce o RIA v MS Akvárku? Dejte o sobě vědět. Děkuji
  • také jste uvažovali o tom, že zkusíte na projekt použít Caliburn Micro nebo naopak Prism 4? A co tak obojí, šlo by to nebo ne? Již brzy