Автор Тема: Data Binding. Start #1  (Прочитано 3448 раз)

Sergey

  • Administrator
  • Newbie
  • *****
  • Сообщений: 14
    • Просмотр профиля
Data Binding. Start #1
« : Декабрь 24, 2012, 03:27:15 pm »
Что получим в итоге:


Выдающихся особенностей в WPF много. И одна из них, без сомнения, Data Binding - связывание данных. Применяться оно может повсюду, в самых разнообразных сценариях. Но, наверное, самая "активная" область применения этой технологии - работа с коллекциями. Иначе, это - область использования как ItemsControl -
Цитировать
Represents a control that can be used to present a collection of items,
так и сложных элементов управления, содержащих свойство ItemsSource или Items. Вот, к примеру, иерархия наследования ListBox и далее, ListView:
System.Object
   System.Windows.Threading.DispatcherObject
     System.Windows.DependencyObject
       System.Windows.Media.Visual
         System.Windows.UIElement
           System.Windows.FrameworkElement
             System.Windows.Controls.Control
               System.Windows.Controls.ItemsControl
                 System.Windows.Controls.Primitives.Selector
                   System.Windows.Controls.ListBox
                     System.Windows.Controls.ListView


Простой пример связывания данных.
Создадим приложение WPF. Разметка окна следующая:
Код: XML
  1. <Window x:Class="MainWindow"
  2.    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.    Title="MainWindow" Height="350" Width="525">
  5.     <Grid>
  6.         <ListBox x:Name="ListBoxProgrammers"
  7.                 ItemsSource="{Binding}">
  8.             <ListBox.ItemTemplate>
  9.                 <DataTemplate>
  10.                     <TextBlock Text="{Binding Path=PC_ProgrammersArea}"/>
  11.                 </DataTemplate>
  12.             </ListBox.ItemTemplate>
  13.         </ListBox>
  14.     </Grid>
  15. </Window>
  16.  

Код главного окна приложения:
Код: Visual Basic
  1. Imports ClassLibrary
  2.  
  3. Class MainWindow
  4.  
  5.     Public Sub New()
  6.  
  7.         ' This call is required by the designer.
  8.        InitializeComponent()
  9.  
  10.         ' Add any initialization after the InitializeComponent() call.
  11.        Dim Programmers As New ProgrammersManagementClass()
  12.         Me.ListBoxProgrammers.DataContext = Programmers.PMC_ProgrammersCollection
  13.     End Sub
  14. End Class
  15.  

Профиль (Enum - перечисление) программиста:
Код: vb.net
  1. Public Module Helper
  2.  
  3.     Public Enum Field
  4.         cpp
  5.         vbnet
  6.         csharp
  7.         php
  8.         maxima
  9.         mathematica
  10.         java
  11.         pascal
  12.     End Enum
  13.  
  14. End Module
  15.  

Код класса ProgrammerClass:
Код: vb.net
  1. Public Class ProgrammerClass
  2.     Public Property PC_ProgrammersName As String
  3.     Public Property PC_ProgrammersArea As Helper.Field
  4.  
  5.     Public Sub New(Name As String, _
  6.                    Area As Helper.Field)
  7.         Me.PC_ProgrammersName = Name
  8.         Me.PC_ProgrammersArea = Area
  9.     End Sub
  10. End Class
  11.  

И, наконец, код класса ProgrammersManagementClass, поставляющего коллекцию. Конечно, в реальности, в качестве поставщика коллекции выступает база данных, XML описание и др.
Код: vb.net
  1. Imports System.Collections.ObjectModel
  2.  
  3. Public Class ProgrammersManagementClass
  4.     Public Property PMC_ProgrammersCollection As ObservableCollection(Of ProgrammerClass)
  5.     Private RandomValue As Random
  6.  
  7.     Public Sub New()
  8.         Me.PMC_ProgrammersCollection = New ObservableCollection(Of ProgrammerClass)()
  9.         Me.RandomValue = New Random()
  10.         For i As Integer = 0 To 10
  11.             Dim NewFormedProgrammer As New ProgrammerClass("Name" & i.ToString, RandomValue.Next(7))
  12.             Me.PMC_ProgrammersCollection.Add(NewFormedProgrammer)
  13.         Next
  14.     End Sub
  15. End Class
  16.  
« Последнее редактирование: Декабрь 24, 2012, 10:01:34 pm от Sergey »

Sergey

  • Administrator
  • Newbie
  • *****
  • Сообщений: 14
    • Просмотр профиля
Data Binding. Start #1 Комментарий
« Ответ #1 : Декабрь 24, 2012, 10:30:27 pm »
Заметим, что нет никакой необходимости использовать конструкцию вида:
Код: XML
  1. <ListBox.ItemTemplate>
  2.                 <DataTemplate>
  3.                     <TextBlock Text="{Binding Path=PC_ProgrammersArea}"/>
  4.                 </DataTemplate>
  5. </ListBox.ItemTemplate>
  6.  
Здесь используется очень мощный инструмент DataTemplate, позволяющий организовать представление данных для "каждого item". Но в нем нет необходимости, поскольку вывод строк не требует никаких дополнительных ухищрений - он организован сам по себе - автоматически, по умолчанию. Другими словами, если заменить вышеприведенную часть следующей
Код: XML
  1. <ListBox x:Name="ListBoxProgrammers"
  2.                 ItemsSource="{Binding}"
  3.                 AlternationCount="2"
  4.                 DisplayMemberPath="PC_ProgrammersArea">
  5. </ListBox>
  6.  
то мы получим тот же результат.
Другое дело - сложное (красочное, пользовательское) представление данных. В подобных случаях используют DataTemplate.

Sergey

  • Administrator
  • Newbie
  • *****
  • Сообщений: 14
    • Просмотр профиля
Data Binding. Start #1 Комментарий
« Ответ #2 : Декабрь 24, 2012, 10:46:51 pm »
Уж очень хочется сделать чередующиеся полосочки в ListBox. WPF - платформа очень богатая, поэтому должно существовать множество вариантов того, как это сделать. Итак, результат будет следующий:


Проще всего, пожалуй, это сделать так:
1. Добавим статический ресурс в код разметки сразу после описания окна.
Код: XML
  1. <Window.Resources>
  2.        <Style TargetType="ListBoxItem">
  3.             <Style.Triggers>
  4.                 <Trigger Property="ItemsControl.AlternationIndex" Value="0">
  5.                     <Setter Property="Background" Value="LightBlue"/>
  6.                 </Trigger>
  7.                 <Trigger Property="ItemsControl.AlternationIndex" Value="1">
  8.                     <Setter Property="Background" Value="Yellow"/>
  9.                 </Trigger>
  10.             </Style.Triggers>
  11.         </Style>
  12. </Window.Resources>
  13.  
Заметим, указание TargetType без указания ключа (или имени) стиля, то есть <Style TargetType="ListBoxItem"> вместо
<Style x:Key="MyListBoxItemStyle" TargetType="ListBoxItem"> приводит к тому, что все списки (существующие и вновь создаваемые в окне) будут отображаться с использованием описанного стиля "в полосочку". Полный код окна, с учетом указанного изменения остается прежним:
Код: XML
  1. <Window x:Class="MainWindow"
  2.    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.    Title="MainWindow" Height="350" Width="525">
  5.     <Window.Resources>
  6.         <Style TargetType="ListBoxItem">
  7.             <Style.Triggers>
  8.                 <Trigger Property="ItemsControl.AlternationIndex" Value="0">
  9.                     <Setter Property="Background" Value="LightBlue"/>
  10.                 </Trigger>
  11.                 <Trigger Property="ItemsControl.AlternationIndex" Value="1">
  12.                     <Setter Property="Background" Value="Yellow"/>
  13.                 </Trigger>
  14.             </Style.Triggers>
  15.         </Style>
  16.     </Window.Resources>
  17.     <Grid>
  18.         <ListBox x:Name="ListBoxProgrammers"
  19.                 ItemsSource="{Binding}"
  20.                 AlternationCount="2"
  21.                 DisplayMemberPath="PC_ProgrammersArea">
  22.         </ListBox>
  23.     </Grid>
  24. </Window>
  25.  
« Последнее редактирование: Декабрь 24, 2012, 10:50:06 pm от Sergey »

Sergey

  • Administrator
  • Newbie
  • *****
  • Сообщений: 14
    • Просмотр профиля
Data Binding. Start #1 Комментарий
« Ответ #3 : Декабрь 24, 2012, 11:12:02 pm »
А как быть, если два списка и с разными стилями.
Желаемый результат таков:

Внесем в код конструктора следующие изменения:
Код: vb.net
  1.  Public Sub New()
  2.  
  3.         ' This call is required by the designer.
  4.         InitializeComponent()
  5.  
  6.         ' Add any initialization after the InitializeComponent() call.
  7.         Dim Programmers As New ProgrammersManagementClass()
  8.         Me.ListBoxProgrammers.DataContext = Programmers.PMC_ProgrammersCollection
  9.         ' Добавляем вторую команду программистов
  10.         Dim ProgrammersAdded As New ProgrammersManagementClass()
  11.         Me.ListBoxProgrammersAdded.DataContext = ProgrammersAdded.PMC_ProgrammersCollection
  12.     End Sub
  13.  
А код разметки перепишем, добавляя ключи к стилю
Код: XML
  1. <Window x:Class="MainWindow"
  2.    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.    Title="MainWindow" Height="350" Width="525">
  5.     <Window.Resources>
  6.         <Style x:Key="MyListBoxItemStyle" TargetType="ListBoxItem">
  7.             <Style.Triggers>
  8.                 <Trigger Property="ItemsControl.AlternationIndex" Value="0">
  9.                     <Setter Property="Background" Value="LightBlue"/>
  10.                 </Trigger>
  11.                 <Trigger Property="ItemsControl.AlternationIndex" Value="1">
  12.                     <Setter Property="Background" Value="Yellow"/>
  13.                 </Trigger>
  14.             </Style.Triggers>
  15.         </Style>
  16.         <Style x:Key="MyListBoxItemStyleAdded" TargetType="ListBoxItem">
  17.             <Style.Triggers>
  18.                 <Trigger Property="ItemsControl.AlternationIndex" Value="0">
  19.                     <Setter Property="Background" Value="Coral"/>
  20.                 </Trigger>
  21.                 <Trigger Property="ItemsControl.AlternationIndex" Value="1">
  22.                     <Setter Property="Background" Value="GreenYellow"/>
  23.                 </Trigger>
  24.             </Style.Triggers>
  25.         </Style>
  26.     </Window.Resources>
  27.     <Grid>
  28.         <DockPanel LastChildFill="False">
  29.             <ListBox x:Name="ListBoxProgrammers"
  30.                         ItemsSource="{Binding}"
  31.                         AlternationCount="2"
  32.                         DisplayMemberPath="PC_ProgrammersArea"
  33.                         ItemContainerStyle="{StaticResource ResourceKey=MyListBoxItemStyle}"  />
  34.             <ListBox x:Name="ListBoxProgrammersAdded"
  35.                 ItemsSource="{Binding}"
  36.                 AlternationCount="2"
  37.                 DisplayMemberPath="PC_ProgrammersArea"
  38.                 ItemContainerStyle="{StaticResource ResourceKey=MyListBoxItemStyleAdded}" />
  39.         </DockPanel>
  40.     </Grid>
  41. </Window>
  42.  
Интересно, но как, например, управлять шириной столбца или "отдельного item"... Пожалуй, без шаблонов не обойтись.
И еще замечание по профилю программистов. Для того, чтобы списки отличались необходимо изменить класс, поставляющий команды программистов:
Код: vb.net
  1. Imports System.Collections.ObjectModel
  2.  
  3. Public Class ProgrammersManagementClass
  4.     Public Property PMC_ProgrammersCollection As ObservableCollection(Of ProgrammerClass)
  5.     Private Shared RandomValue As New Random()
  6.  
  7.     Public Sub New()
  8.         Me.PMC_ProgrammersCollection = New ObservableCollection(Of ProgrammerClass)()
  9.         For i As Integer = 0 To 10
  10.             Dim NewFormedProgrammer As New ProgrammerClass("Name" & i.ToString, RandomValue.Next(7))
  11.             Me.PMC_ProgrammersCollection.Add(NewFormedProgrammer)
  12.         Next
  13.     End Sub
  14. End Class
  15.  
Продолжение следует...
« Последнее редактирование: Декабрь 24, 2012, 11:18:08 pm от Sergey »