понедельник, 20 мая 2013 г.

WPF. Динамічний вибір шаблона використовуючи клас DataTemplateSelector

Буває ситуація, коли заздалегідь не знаєш, який шаблон даних необхідно підключити або в залежності від значення об'єкта потрібно використати інший шаблон даних . Для цього WPF передбачає DataTemplateSelector.



DataTemplateSelector -  забезпечує можливість вибрати DataTemplate на основі даних об'єкта .
Уявімо, що маємо завдання у лістбоксі, який представляє список автомобілів, необхідно візуально виокремити продані   і не продані автомобілі. Такий функціонал можна досягти за допомогою  класу DataTemplateSelector, застосувавши в лістбоксі для проданих автомобілів один шаблон ,  а для не проданих – інший.
В прикладі буде використовуватись модель Car 
   1: class Car

   2:     {

   3:         public bool IsSold { get; set; }

   4:         public string Name { get; set; }

   5:         public int Price { get; set; }

   6:         public int Year { get; set; }

   7:     }

, де пропертя IsSold = true означає , що автомобіль проданий і навпаки.

Step 1. Створити необхідні шаблони даних для представлення даних.


   1: <DataTemplate x:Key="CarsDataTemplate">

   2:                <Border BorderBrush="Green"  BorderThickness="3">

   3:                    <Grid>

   4:                        <Grid.ColumnDefinitions>

   5:                            <ColumnDefinition Width="*"></ColumnDefinition>

   6:                            <ColumnDefinition Width="*"></ColumnDefinition>

   7:                            <ColumnDefinition Width="*"></ColumnDefinition>

   8:                            <ColumnDefinition Width="*"></ColumnDefinition>

   9:                            <ColumnDefinition Width="*"></ColumnDefinition>

  10:                        </Grid.ColumnDefinitions>

  11:                        <Label Grid.Column="1" Content="{Binding Name}"></Label>

  12:                        <Label Grid.Column="2" Content="{Binding Price}"></Label>

  13:                        <Label Grid.Column="3" Content="{Binding Year}"></Label>

  14:                        <Image Grid.Column="4" Source="/Images/forsale.jpg" Stretch="Fill"></Image>

  15:                    </Grid>

  16:                </Border>

  17:               

  18:            </DataTemplate>

  19:  

  20:  

  21:            <DataTemplate x:Key="SoldCarsDataTemplate">

  22:                <Border BorderBrush="Red" BorderThickness="3">

  23:                    <Grid>

  24:                        <Grid.ColumnDefinitions>

  25:                            <ColumnDefinition Width="*"></ColumnDefinition>

  26:                            <ColumnDefinition Width="*"></ColumnDefinition>

  27:                            <ColumnDefinition Width="*"></ColumnDefinition>

  28:                            <ColumnDefinition Width="*"></ColumnDefinition>

  29:                            <ColumnDefinition Width="*"></ColumnDefinition>

  30:                        </Grid.ColumnDefinitions>

  31:                        <Label Grid.Column="1" Content="{Binding Name}"></Label>

  32:                        <Label Grid.Column="2" Content="{Binding Price}"></Label>

  33:                        <Label Grid.Column="3" Content="{Binding Year}"></Label>

  34:                        <Border Grid.Column="4" BorderBrush="Red" BorderThickness="1" >

  35:                            <Label Content="This car is already sold!!!" Background="Yellow"></Label>

  36:                        </Border>

  37:                       

  38:  

  39:                    </Grid>

  40:                </Border>

  41:  

  42:            </DataTemplate>

Step 2. Створити клас який буде наслідуватись від класу DataTemplateSelector і оверрайднути метод SelectTemplate. 


   1: class CarTempleteSelector : DataTemplateSelector

   2:    {

   3:        public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)

   4:        {

   5:            FrameworkElement element = container as FrameworkElement;

   6:  

   7:            if (item != null && item is Car && ((Car)item).IsSold)

   8:            {

   9:                return element.FindResource("SoldCarsDataTemplate") as DataTemplate;

  10:            }

  11:            else

  12:            {

  13:                return element.FindResource("CarsDataTemplate") as DataTemplate;

  14:            }

  15:  

  16:        }

  17:    }



Метод SelectTemplate    повертає DataTemplate на основі значення об'єкта .

Step 3. Присвоїти значення проперті лістбокса -  ItemTemplateSelector.


  • визначити ресурс


   1:  

   2:         <shared:CarTempleteSelector x:Key="CarsTemplateSelector"></shared:CarTempleteSelector>







  • встановити значення для проперті лістбокса ItemTemplateSelector


   1: <ListBox ItemsSource="{Binding CarDatabase}" ItemTemplateSelector="{StaticResource CarsTemplateSelector}"></ListBox>

Cкачати приклад

Комментариев нет:

Отправить комментарий