Использование DataBinding и DataTemplate при помощи Expression Blend в Silverlight - Реализация LibraryList_SelectionChanged

ОГЛАВЛЕНИЕ

Реализация LibraryList_SelectionChanged

Когда пользователь щелкает по книге, вызывается обработчик события LibraryList_SelectionChanged, который выполнит следующие действия:

  1. Изменение размера списка, путем уменьшения его для отображения одной строки
  2. Установка видимости табличной сетки деталей
  3. Установка объекта Book (selectedBook) в значение книги, выбранной пользователем
  4. Установка dataContext для всех элементов управления для выбранной книги путем установки DataContext в DetailsGrid
  5. Вызов события PropertyChanged из Book для того, чтобы обновить пользовательский интерфейс.

Создание второго элемента Grid

Вернитесь в Blend и скройте список LibraryList щелкнув по иконке в виде глаза в закладке Objects and Timeline, как это показано на рисунке 7-24

Рисунок 7-24. Сокрытие LibraryList

Вставтье табличную сетку, а именно DetailsGrid, в третью строку существующей табличной сетки и используйте свойства stretch и margin (=0) для того, чтобы новая табличная сетка занимала полностью строку. Разделите DetailsGrid на шесть строк и две колонки и добавьте элементы управления, как это показано на рисунке 7-25

Рисунок 7-25. DetailsGrid, разделенный на шесть строк и две колонки

Привязка элементов управления в табличной сетке DetailsGrid

В правой части DetailsGrid в шести строках расположены восемь элементов управления, хотя на рисунке 7-24 шесть из них не видны (это элементы TextBlock без текста). Самым легким путем описания их позиции, атрибутов и привязки будет демонстрация Xaml, хотя их создавать вы будете не в Xaml, а скорее перетащив элементы TextBlock в Artboard и установив их свойства.

Давайте предположим следующее:

VerticalAlignment=”Bottom”
HorizontalAlignment=”Right”
FontFamaily=”Verdana”
FontSize=”18”
FontWeight="Medium" 

Хотя Xaml гласит иначе.

<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" >
   <TextBlock x:Name="NumAuthorsPrompt" 
   Text="{Binding NumAuthors, Mode=OneWay}"
   Margin="0,0,15,15"/>
   <TextBlock x:Name="AuthorsPrompt" Text="Authors"
   Margin="0,0,15,15"/>
</StackPanel>
          
<ListBox x:Name="AuthorsListBox"
  Height="Auto" Width="Auto"
  HorizontalAlignment="Stretch"
  VerticalAlignment="Stretch"
  Grid.Column="1" Grid.Row="0" Margin="10,0,20,0"
  ItemsSource="{Binding Authors, Mode=OneWay}">
   <ListBox.ItemTemplate>
     <DataTemplate>
       <StackPanel Orientation="Horizontal" Margin="5">
         <TextBlock
           FontSize="14"
           Foreground="Black"
           Text="{Binding Name}"/>
       </StackPanel>
     </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>
      
<TextBlock x:Name="PublisherPrompt" Grid.Row="1" Grid.Column="0"
Text="Publisher" Margin="0,0,15,15"/>
          
<TextBlock x:Name="Publisher" Grid.Row="1" Grid.Column="1"
HorizontalAlignment="Left" Height="Auto" Width="Auto" Margin="10,0,15,15"
Text="{Binding Publisher}" />
   
<TextBlock x:Name="EditionPrompt" Grid.Row="2" Grid.Column="0"
Text="Edition" Margin="0,0,15,15"/>

<TextBlock x:Name="Edition" Grid.Row="2" Grid.Column="1"
HorizontalAlignment="Left" Height="Auto" Width="Auto" Margin="10,0,15,15"
Text="{Binding Edition}" />
  
<TextBlock x:Name="PrintingPrompt" Grid.Row="3" Grid.Column="0"
Text="Printing" Margin="0,0,15,15"/>

<TextBlock x:Name="Printing" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Left"
Height="Auto" Width="Auto" Margin="10,0,15,15"  
Text="{Binding Printing}" />

<TextBlock x:Name="YearPrompt" Grid.Row="4" Grid.Column="0"
Text="Publication Year" Margin="0,0,15,15"/>

<TextBlock x:Name="Year" Grid.Row="4" Grid.Column="1"
HorizontalAlignment="Left" Height="Auto" Width="Auto"
Margin="10,0,15,15" Text="{Binding PubYear}" />  

<TextBlock x:Name="RatingPrompt" Grid.Row="5" Grid.Column="0"
Text="Rating" Margin="0,0,15,15"/>  

<StackPanel Grid.Row="5" Margin="0,0,0,15" Grid.Column="1"
Orientation="Horizontal" > 

<Slider x:Name="RatingSlider" Width="150"
HorizontalAlignment="Left" Margin="5,0,5,0"
LargeChange="1.0" SmallChange="0.1"
Minimum="0" Maximum="5.0" ValueChanged="RatingSlider_ValueChanged"
Value="{Binding Rating, Mode=TwoWay }" /> 

<TextBlock x:Name="SliderValueDisplay" Margin="5,0,0,0"
HorizontalAlignment="Left" />

</StackPanel>
</Grid> 

Сокрытие DetailsGrid

Вам необходимо сделать данную сетку невидимой тогда, когда внешняя табличная сетка (LayoutControl) отображается первой, а потому измените свойство видимости (Visibility) (line 65) в Visibility="Visible" на Visibility="Collapsed" и для удобства спрячьте список Library в закладке Objects and Timeline.

Создание обработчиков события

Вам необходим обработчик события для перехода из одного режима в другой, а также вам необходим обработчик события для изменений ползунка (обратите внимание на внутреннее событие "ValueChanged").

Изменение размера элементов List Box

Установка размера зависит от корректной установки отступов. Отступы, как оказалось, являются экземплярами класса Thickness. Что касается установки ListBox на отображение всего одной строки, то тут мы должны использовать свойство элемента Grid, и для этого мы применим метод SetValue, передавая свойство элемента Grid и значение, которое мы хотим установить.

private void LibraryList_SelectionChanged(
   object sender,
    System.Windows.Controls.SelectionChangedEventArgs e)
{
    LibraryList.Margin = new Thickness(50, 5, 20, 5);
    LibraryList.SetValue(Grid.RowSpanProperty, 1); 

Если вам интересно посмотреть, как это работает, найдите LayoutRoot (верхний элемент Grid) и добавьте ShowGridLines="True" - и затем запустите программу и щелкните по книжке. Вы должны увидеть уменьшенный список между пунктирными линиями, как это показано на рисунке 7-26

Рисунок 7-26. Уменьшенный ListBox в первой строке

Вернувшись в обработчик события, Details Grid обладает свойством видимости, при этом Intellisense поможет вам установить свойства в перечисляемое значение
Visibility.Visible

Установка объекта Book (selectedBook) в выбранную пользователем книгу

Выбранная книга перейдет в ваш метод посредством SelectionChangedEventArgs в качестве первого члена набора AddedItems. Это будет тем объектом, чей нижележащий тип является Book, и вы можете преобразовать его соответственно.

Book selectedBook = e.AddedItems[0] as Book;

Установка dataContext для всех элементов управления в выбранную книгу путем установки DataContext элемента DetailsGrid

Все элементы управления в пределах контейнера наследует DataContext самого контейнера в случае, если они их не перегружают. Потому нет особых причин в написании,

Printing.Text = selectedBook.Printing.ToString();
PublicationYear.Text = selectedBook.PubYear.ToString(); 

и т.д. Вместо этого вы можете просто привязать текст данных объектов так же, как мы это делали раньше, и установить DataContext их контейнера,

DetailsGrid.DataContext = selectedBook;

Запустите программу и наблюдайте все в действии

Рисунок 7-27. Запущенная программа