Просмотр сообщений

В этом разделе можно просмотреть все сообщения, сделанные этим пользователем.


Сообщения - Sergey

Страницы: [1]
1
В большей мере о WPF / Template, Style, Trigger. Sample #1
« : Январь 21, 2013, 12:58:06 am »
Сегодня мы рассмотрим пример, в котором используются стиль, шаблон и триггер (Template, Style and Trigger). Перечисленные инструменты, в большей степени характерные для XAML, позволяют самым удивительным образом настраивать интерфейс пользователя.

Итак, задача будет состоять в том, чтобы настроить классический ToggleButton (кнопка с залипанием). Именно, в зависимости от того, нажата ли кнопка или нет, показывать соответствующий значок.
Инструментарий: Expression Blend, Expression Design, Visual studio.
Expression Design - великолепный графический инструмент для подготовки векторной графики и изображений для последующего использования в проектировании UI - интерфейса пользователя. Самое привлекательное состоит в том, что формат сохранения векторной графики может быть в том числе и XAML с контейнером Canvas и (или) Viewbox. Сочетание последних контейнеров предназначено именно для отображения графики. Если чуть глубже, то в этих контейнерах реализовано адаптированное расположение графических элементов, основанное на их действительных размерах.

Результат представлен рисунком ниже:


Итак, файл кода остается совершенно пустым - все реализуется в XAML. Код экземпляра, унаследованного от Window имеет вид
Код: 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.    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.    Title="MainWindow" Height="156" Width="291">
  6.         <Window.Resources>
  7.                 <ResourceDictionary>
  8.                         <ResourceDictionary.MergedDictionaries>
  9.                                 <ResourceDictionary Source="TSResources.xaml"/>
  10.                         </ResourceDictionary.MergedDictionaries>
  11.                 </ResourceDictionary>
  12.         </Window.Resources>
  13.     <Grid>
  14.         <Grid.ColumnDefinitions>
  15.             <ColumnDefinition/>
  16.         </Grid.ColumnDefinitions>
  17.         <Grid.RowDefinitions>
  18.             <RowDefinition Height="Auto"/>
  19.             <RowDefinition/>
  20.         </Grid.RowDefinitions>
  21.         <Grid.Background>
  22.             <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  23.                 <GradientStop Color="Black" Offset="0"/>
  24.                 <GradientStop Color="White" Offset="1"/>
  25.             </LinearGradientBrush>
  26.         </Grid.Background>
  27.         <DockPanel
  28.                   LastChildFill="False"
  29.                   Grid.RowSpan="1"
  30.                   Grid.Row="0"
  31.                   Grid.Column="0">
  32.             <ToggleButton MinWidth="50" MinHeight="30"
  33.                         Style="{StaticResource OpenCloseStyle}">
  34.             </ToggleButton>
  35.             <ToggleButton MinWidth="50" MinHeight="30"
  36.                 Style="{StaticResource OpenCloseStyle}"/>
  37.             <ToggleButton MinWidth="50" MinHeight="30"
  38.                 Style="{StaticResource OpenCloseStyle}"/>
  39.         </DockPanel>
  40.     </Grid>
  41. </Window>
  42.  
Ясно, что вся "основная" работа по настройке вида кнопки происходит в словаре ресурсов - в файле TSResources.xaml.
Его код представлен ниже:
Код: XML
  1. <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  2.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  
  3.         <DataTemplate x:Key="ArrowToOpen">
  4.         <Viewbox
  5.                         Height="20" Width="20">
  6.             <Canvas Width="122.717" Height="82.377" Clip="F1 M 0,0L 122.717,0L 122.717,82.377L 0,82.377L 0,0">
  7.                 <Path Width="122.717" Height="82.377" Stretch="Fill" StrokeThickness="2.88" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 61.172,80.937L 41.5788,61.3659L 2.90447,22.7035C 0.951843,20.7509 0.951843,17.585 2.90447,15.6324L 15.6324,2.9045C 17.585,0.951859 20.7508,0.951859 22.7035,2.9045L 61.2962,41.5235L 100.014,2.9045C 101.966,0.951859 105.132,0.951859 107.085,2.9045L 119.813,15.6324C 121.765,17.585 121.765,20.7508 119.813,22.7034L 81.2563,61.26L 61.172,80.937 Z "/>
  8.             </Canvas>
  9.         </Viewbox>
  10.     </DataTemplate>
  11.     <DataTemplate x:Key="ArrowToClose">
  12.         <Viewbox
  13.                         Height="20" Width="20">
  14.             <Canvas Width="82.377" Height="122.717" Clip="F1 M 0,0L 82.377,0L 82.377,122.717L 0,122.717L 0,0">
  15.                 <Path Width="82.377" Height="122.717" Stretch="Fill" StrokeThickness="2.88" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 80.937,61.5453L 61.3658,81.1385L 22.7035,119.813C 20.7509,121.765 17.585,121.765 15.6324,119.813L 2.90448,107.085C 0.951843,105.132 0.951843,101.966 2.90448,100.014L 41.5234,61.421L 2.90442,22.7034C 0.951782,20.7507 0.951782,17.585 2.90442,15.6323L 15.6323,2.90442C 17.585,0.951782 20.7508,0.951782 22.7034,2.90442L 61.2599,41.4609L 80.937,61.5453 Z "/>
  16.             </Canvas>
  17.         </Viewbox>
  18.     </DataTemplate>
  19.         <Style x:Key="OpenCloseStyle" TargetType="ToggleButton">
  20.                 <Style.Triggers>
  21.                         <Trigger Property="IsChecked" Value="False">
  22.                                 <Setter Property="ContentTemplate" Value="{StaticResource ArrowToOpen}"></Setter>
  23.                         </Trigger>
  24.                         <Trigger Property="IsChecked" Value="True">
  25.                                 <Setter Property="ContentTemplate" Value="{StaticResource ArrowToClose}"></Setter>
  26.                         </Trigger>
  27.                 </Style.Triggers>
  28.         </Style>
  29. </ResourceDictionary>
  30.  
Обратим внимание на два обстоятельства:
1. В Visual Studio строка ссылки на файл ресурсов Source="TSResources.xaml" воспринимается ошибкой. Мы выбрали Expression Blend - здесь есть удивительная особенность. После создания файла ресурсов перейдя во вкладку ресурсов справа, "залинковать" ресурс, например, к окну приложения. В частности, следующая часть кода вставлена автоматически Expression Blend.



Затронутый вопрос указания ссылки на файл в XAML, да и шире, вопрос подключения, скажем, внешнего класса (класса из проекта библиотеки в другой сборке) в область видимости файла XAML - довольно каверзная вещь. Например, опытным путем замечено, что файл XAML может не видеть класс "сторонней" библиотеки, хотя внешне все сделано правильно. Часто оказывается достаточным просто перекомпилировать решение при выставленной опции Any CPU (Build -> Configuration Manager). Удивительно, но факт довольно неприятный, особенно когда часами тщетно пытаешься найти причину ошибки.
Код: XML
  1.         <Window.Resources>
  2.                 <ResourceDictionary>
  3.                         <ResourceDictionary.MergedDictionaries>
  4.                                 <ResourceDictionary Source="TSResources.xaml"/>
  5.                         </ResourceDictionary.MergedDictionaries>
  6.                 </ResourceDictionary>
  7.         </Window.Resources>
  8.  
2. Строки вида "F1 M 0,0L 82.377,0L 82.377,122.717L 0,122.717L 0,0" указывают на язык (скрипт) плоской графики, применяемый дополнительно внутри XAMl. Ничто не мешает им пользоваться и непосредственно в коде.


2
В большей мере о WPF / Data Binding. Start #2 Custom Sort
« : Декабрь 27, 2012, 08:41:54 pm »
Пользовательская сортировка.

Случаев, когда может понадобиться указанная особенность очень много. Основная идея - автоматизированный (встроенный) механизм сравнения. Итак, добавляем третью колонку в ListView:
Код: XML
  1. <!-- Third Column -->
  2. <GridViewColumn DisplayMemberBinding="{Binding SpammIndexInForums}">
  3.                     <GridViewColumn.Header>
  4.                         <TextBlock Text="Spamm Index"/>
  5.                     </GridViewColumn.Header>
  6. </GridViewColumn>
  7.  
Как видим, отображаемые данные завязаны на SpammIndexInForums - новое свойство у StudentClass. Добавим это свойство и изменим конструктор класса
Код: vb.net
  1. Public Sub New(StudentName As String, _
  2.                    StudentAge As String, _
  3.                    SpammIndex As Integer)
  4.         Me.StudentName = StudentName
  5.         Me.Age = StudentAge
  6.         Me.SpammIndexInForums = SpammIndex
  7. End Sub
  8.  
Функцию, генерирующую коллекцию студентов перепишем в виде
Код: vb.net
  1. Public Sub GetStudentsGroup()
  2.         Dim NewFormedCollection = New ObservableCollection(Of StudentClass)
  3.         NewFormedCollection.Add(New StudentClass() With
  4.                                 {.StudentName = "Nicola", .Age = "39", .SpammIndexInForums = 3})
  5.         NewFormedCollection.Add(New StudentClass() With _
  6.                                 {.StudentName = "Peter", .Age = "43", .SpammIndexInForums = 5})
  7.         NewFormedCollection.Add(New StudentClass() With _
  8.                                 {.StudentName = "Sergey", .Age = "24", .SpammIndexInForums = 2})
  9.         NewFormedCollection.Add(New StudentClass() With _
  10.                                 {.StudentName = "Jan", .Age = "34", .SpammIndexInForums = 0})
  11.         NewFormedCollection.Add(New StudentClass() With _
  12.                                 {.StudentName = "Jeorge", .Age = "18", .SpammIndexInForums = 4})
  13.  
  14.         For i As Integer = 0 To 5
  15.             NewFormedCollection.Add(New StudentClass() With {.StudentName = "Boris" & i.ToString,
  16.                                                              .Age = (58 - i).ToString, _
  17.                                                              .SpammIndexInForums = 6 - i})
  18.         Next
  19.  
  20.         Me.StudentsGroup = NewFormedCollection
  21.     End Sub
  22.  
В StackPanel добавим третью кнопку - пользовательская сортировка, а обработчик события для нее наполним следующим содержанием:
Код: vb.net
  1.  Private Sub BtnSpammSort_Click(sender As Object, e As RoutedEventArgs) Handles BtnSpammSort.Click
  2.         ' ========================
  3.         CurrentViewOfStudents.SortDescriptions.Clear()
  4.         CurrentViewOfStudents.CustomSort = New ComparerSpammer()
  5.         ' ========================
  6.     End Sub
  7.  
Получаем следующий результат сортировки по "индексу спама, посылаемого студентом":

И, наконец, важная вещь, делающая возможной такую сортировку - объявление и приведение коллекции к особому виду. Изменения в коде главного окна:
Код: vb.net
  1. ' Dim CurrentViewOfStudents As ICollectionView
  2.     Dim CurrentViewOfStudents As ListCollectionView
  3.     Public Sub New()
  4.  
  5.         ' This call is required by the designer.
  6.         InitializeComponent()
  7.  
  8.         ' Add any initialization after the InitializeComponent() call.
  9.         CurrentViewOfStudents = CType(
  10.          CollectionViewSource.GetDefaultView(ListBoxStudentsName.ItemsSource), ListCollectionView)
  11.     End Sub
  12.  
Продолжение следует...

3
Довольная хитрая вещь кроется в разметке
Код: XML
  1. <GridViewColumn.CellTemplate>
  2.                             <DataTemplate>
  3.                                 <TextBlock Text="{Binding Age}"/>
  4.                             </DataTemplate>
  5. </GridViewColumn.CellTemplate>
  6.  
В нашем случае, при отображении лишь простого текста, нет необходимости в использовании шаблона ячейки. Есть, как всегда, "встроенное чудо" под названием DisplayMemberBinding. Формат его таков:
Код: XML
  1. <GridView>
  2.                     <!-- First Column -->
  3.                     <GridViewColumn DisplayMemberBinding="{Binding StudentName}">
  4.                         <GridViewColumn.Header>
  5.                             <TextBlock Text="Name"/>
  6.                         </GridViewColumn.Header>
  7.                     </GridViewColumn>
  8.                     <!-- Second Column -->
  9.                     <GridViewColumn DisplayMemberBinding="{Binding Age}">
  10.                         <GridViewColumn.Header>
  11.                             <TextBlock Text="Age"/>
  12.                         </GridViewColumn.Header>
  13.                     </GridViewColumn>
  14. </GridView>
  15.  
Результат выполнения кода остается прежним.

4
Как провести сортировку "одновременно" - по двум свойствам? И как отображать сразу два свойства?

Изменим разметку главного окна, окультурив контейнеры (Grid, добавим StackPanel) и добавив вторую кнопку сортировки:
Код: XML
  1. <Window
  2.    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.    xmlns:classes="clr-namespace:ClassLibrary;assembly=ClassLibrary"
  5.    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MainWindow"
  6.    Title="MainWindow" d:DesignWidth="244.5" d:DesignHeight="318">
  7.     <Window.Resources>
  8.         <classes:StudentCollectionClass x:Key="StudentCollectionInstance"/>
  9.     </Window.Resources>
  10.     <Grid>
  11.         <Grid.ColumnDefinitions>
  12.             <ColumnDefinition Width="Auto"/>
  13.             <ColumnDefinition/>
  14.         </Grid.ColumnDefinitions>
  15.         <ListView Background="LightGreen"
  16.                         x:Name="ListBoxStudentsName"
  17.                         ItemsSource="{Binding StudentsGroup,
  18.                          Source={StaticResource StudentCollectionInstance}}"
  19.                         MinWidth="200" Grid.Column="1">
  20.             <ListView.View>
  21.                 <GridView>
  22.                     <!-- First Column -->
  23.                     <GridViewColumn>
  24.                         <GridViewColumn.CellTemplate>
  25.                             <DataTemplate>
  26.                                 <TextBlock Text="{Binding StudentName}"/>
  27.                             </DataTemplate>
  28.                         </GridViewColumn.CellTemplate>
  29.                         <GridViewColumn.Header>
  30.                             <TextBlock Text="Name"/>
  31.                         </GridViewColumn.Header>
  32.                     </GridViewColumn>
  33.                     <!-- Second Column -->
  34.                     <GridViewColumn>
  35.                         <GridViewColumn.CellTemplate>
  36.                             <DataTemplate>
  37.                                 <TextBlock Text="{Binding Age}"/>
  38.                             </DataTemplate>
  39.                         </GridViewColumn.CellTemplate>
  40.                         <GridViewColumn.Header>
  41.                             <TextBlock Text="Age"/>
  42.                         </GridViewColumn.Header>
  43.                     </GridViewColumn>
  44.                 </GridView>
  45.             </ListView.View>
  46.         </ListView>
  47.         <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top">
  48.             <Button x:Name="BtnSort"
  49.                                 Content="Sort Name"
  50.                                 HorizontalAlignment="Left"
  51.                                 VerticalAlignment="Top"
  52.                                 Width="75"/>
  53.             <Button x:Name="BtnSortAge"
  54.                                 Content="Sort Age"
  55.                                 HorizontalAlignment="Left"
  56.                                 VerticalAlignment="Top"
  57.                                 Width="75"/>
  58.         </StackPanel>
  59.     </Grid>
  60. </Window>
  61.  
Конечно, можно было бы "вкладывать" свойства-описания элементов внутрь тегов XAML, сократив немного код. Но приведенный подход демонстрирует "принцип глубокой вложенности" элементов XAML.
Изменим код главного окна:
Код: vb.net
  1. Imports System.ComponentModel
  2.  
  3. Class MainWindow
  4.     Dim CurrentViewOfStudents As ICollectionView
  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.         CurrentViewOfStudents = _
  12.          CollectionViewSource.GetDefaultView(ListBoxStudentsName.ItemsSource)
  13.     End Sub
  14.  
  15.     Private Sub BtnSort_Click(sender As Object, e As RoutedEventArgs) Handles BtnSort.Click
  16.         ' ========================
  17.         CurrentViewOfStudents.SortDescriptions.Clear()
  18.         CurrentViewOfStudents.SortDescriptions.Add(New SortDescription("StudentName", _
  19.                                                        ListSortDirection.Ascending))
  20.         ' ========================
  21.     End Sub
  22.  
  23.     Private Sub BtnSortAge_Click(sender As Object, e As RoutedEventArgs) Handles BtnSortAge.Click
  24.         ' ========================
  25.         CurrentViewOfStudents.SortDescriptions.Clear()
  26.         CurrentViewOfStudents.SortDescriptions.Add(New SortDescription("Age", _
  27.                                                        ListSortDirection.Ascending))
  28.         ' ========================
  29.     End Sub
  30. End Class
  31.  
И немного "разнообразим" возрасты студентов в классе - поставщике StudentCollectionClass
Код: vb.net
  1. For i As Integer = 0 To 5
  2.             NewFormedCollection.Add(New StudentClass() With _
  3.                                                            {.StudentName = "Boris" & i.ToString,
  4.                                                              .Age = (58 - i).ToString})
  5. Next
  6.  
Получаем следующий результат:


Последовательное нажатие кнопок приводит к сортировке по имени или возрасту.

5
Интересно, а как сортировать по возрасту?

Изменим в классе StudentCollectionClass - поставщике коллекции, код добавления новых студентов в цикле. Это совсем не обязательный шаг - просто для того, чтобы было больше студентов с отличающимися возрастами.
Код: vb.net
  1.  For i As Integer = 0 To 5
  2.             NewFormedCollection.Add(New StudentClass() With
  3.                        {.StudentName = "Boris" & i.ToString,
  4.                          .Age = (18 + i).ToString})
  5. Next
  6.  
В обработчике события кнопки Sort добавим новое описание сортировки и закомментируем "старое":
Код: vb.net
  1. Private Sub BtnSort_Click(sender As Object, e As RoutedEventArgs) Handles BtnSort.Click
  2.         Dim CurrentViewOfStudents As ICollectionView = _
  3.            CollectionViewSource.GetDefaultView(ListBoxStudentsName.ItemsSource)
  4.         ' ========================
  5.         'CurrentViewOfStudents.SortDescriptions.Add(New SortDescription("StudentName", _
  6.         '                                               ListSortDirection.Ascending))
  7.         CurrentViewOfStudents.SortDescriptions.Add(New SortDescription("Age", _
  8.                                                        ListSortDirection.Ascending))
  9.         ' ========================
  10.     End Sub
  11.  
В коде разметки главного окна изменим отображаемое свойство элементов списка так:
Код: XML
  1. DisplayMemberPath="Age"
После нажатия кнопки сортировки получаем результат:

6
Продемонстрируем возможности сортировки в связанном списке на простом примере.

Будем работать с коллекцией студентов, отображаемых в ListBox с помощью Binding.
Заметим, связывание ListBox с коллекцией возможно двумя способами:
  • Назначением коллекции в коде через ItemsSource или DataContext (см. пример Data Binding. Start #1)
  • Назначением коллекции в качестве источника данных непосредственно в XAML. Интересно подметить, что в этом случае за кулисами (без нашего участия) создается экземпляр класса, поставляющий данные для ListBox. Мы лишь должны описать эту работу в XAML.
В рамках данного примера продемонстрируем второй способ.
Обычно создается класс, поставляющий данные. Лучше его расположить в отдельном проекте (рядом с другими классами, работающими на приложение и не имеющими прямого отношения к интерфейсу). Тип проекта может быть либо ClassLibrary, либо WPF User Control Library (в некоторых интересных случаях). Код класса студента очень прост. Кроме имени мы добавили сюда еще и возраст.
Код: vb.net
  1. Public Class StudentClass
  2.  
  3.     Public Property Age As Integer
  4.     Public Property StudentName As String = String.Empty
  5.  
  6.     Public Sub New(StudentName As String, _
  7.                    StudentAge As String)
  8.         Me.StudentName = StudentName
  9.         Me.Age = StudentAge
  10.     End Sub
  11.  
  12.     Public Sub New()
  13.  
  14.     End Sub
  15. End Class
  16.  
Теперь необходимо в главном проекте указать ссылку на библиотеку классов, в которой располагается наш класс студента. Далее, создадим класс, который будет поставлять студентов. Именно, коллекцию студентов. Использование в качестве коллекции ObservableCollection не случайно. Для особо пытливых скажем, что она (эта коллекция) имеет встроенное уведомление об изменении). Если не очень ясно - забудем об этих "глупостях". Код класса - поставщика студентов имеет вид:
Код: vb.net
  1. Imports System.Collections.ObjectModel
  2.  
  3. Public Class StudentCollectionClass
  4.  
  5.     Private _StudentsGroup As ObservableCollection(Of StudentClass)
  6.     Public Property StudentsGroup As ObservableCollection(Of StudentClass)
  7.         Get
  8.             Return _StudentsGroup
  9.         End Get
  10.         Set(value As ObservableCollection(Of StudentClass))
  11.             _StudentsGroup = value
  12.         End Set
  13.     End Property
  14.  
  15.     Public Sub GetStudentsGroup()
  16.  
  17.         Dim NewFormedCollection = New ObservableCollection(Of StudentClass)
  18.         NewFormedCollection.Add(New StudentClass() With {.StudentName = "Nicola", .Age = "39"})
  19.         NewFormedCollection.Add(New StudentClass() With {.StudentName = "Peter", .Age = "43"})
  20.         NewFormedCollection.Add(New StudentClass() With {.StudentName = "Sergey", .Age = "24"})
  21.         NewFormedCollection.Add(New StudentClass() With {.StudentName = "Jan", .Age = "34"})
  22.         NewFormedCollection.Add(New StudentClass() With {.StudentName = "Jeorge", .Age = "18"})
  23.  
  24.         For i As Integer = 0 To 5
  25.             NewFormedCollection.Add(New StudentClass() With {.StudentName = "Boris" & i.ToString,
  26.                                                              .Age = "18"})
  27.         Next
  28.  
  29.         Me.StudentsGroup = NewFormedCollection
  30.     End Sub
  31.  
  32.     Public Sub New()
  33.         Me.GetStudentsGroup()
  34.     End Sub
  35.  
  36. End Class
  37.  

Код разметки главного окна имеет вид:
Код: 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.    xmlns:classes="clr-namespace:ClassLibrary;assembly=ClassLibrary"
  5.    Title="MainWindow" Height="350" Width="525">
  6.     <Window.Resources>
  7.         <classes:StudentCollectionClass x:Key="StudentCollectionInstance"/>
  8.     </Window.Resources>
  9.     <Grid>
  10.         <ListBox Background="LightGreen"
  11.                 x:Name="ListBoxStudentsName"
  12.                 VerticalAlignment="Top"
  13.                 Width="100"
  14.                 ItemsSource="{Binding Source={StaticResource StudentCollectionInstance}, Path=StudentsGroup}"
  15.                 DisplayMemberPath="StudentName"
  16.                 MinWidth="200"/>
  17.     </Grid>
  18. </Window>
  19.  

Два слова об особенностях. В классе коллекции студентов просто обязан присутствовать пустой конструктор, - иначе XAML не поймет что и каким образом создавать. На практике, мы попросту не увидим ссылку в подсказках студии на возможный класс:
<classes:StudentCollectionClass x:Key="StudentCollectionInstance"/>. Это - общее правило использования статических ресурсов (внешних классов) в XAML.
Получаем следующее:


Приступим к простейшей сортировке. Чтобы видеть отчетливее результат наших действий, поместим кнопку в окне, по которой будем инициировать сортировку по именам студентов. Добавим к кнопке следующий обработчик события:
Код: vb.net
  1.  Private Sub BtnSort_Click(sender As Object, e As RoutedEventArgs) Handles BtnSort.Click
  2.         Dim CurrentViewOfStudents As ICollectionView = _
  3.            CollectionViewSource.GetDefaultView(ListBoxStudentsName.ItemsSource)
  4.         ' ========================
  5.         CurrentViewOfStudents.SortDescriptions.Add(New SortDescription("StudentName", _
  6.                                                        ListSortDirection.Ascending))
  7.         ' ========================
  8.     End Sub
  9.  
Потребуется также подключение библиотеки Imports System.ComponentModel
Теперь, по нажатию кнопки, наш список сортируется по именам студентов.

7
В большей мере о WPF / Data Binding. Start #1 Комментарий
« : Декабрь 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.  
Продолжение следует...

8
В большей мере о WPF / Data Binding. Start #1 Комментарий
« : Декабрь 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.  

9
В большей мере о WPF / Data Binding. Start #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.

10
В большей мере о WPF / 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.  

11
В нашей Медиа части появилось первое видео из серии Сопромат XXI. Оно посвящено численным расчетам балок на изгиб в
Тимик.
Важно. Указанная ссылка доступна зарегистрированным пользователям.

Ну а для тех, кто регистрироваться не желает, приглашаем к youtube просмотру
Изгиб балки онлайн. Сопромат XXI. helper.orlovsoft.com

12
Если Вы интересуетесь установкой и использованием втечение некоторого времени программ Timo Structural и(или) Mechanics of Materials Toolbox for Maple, пришлите свой запрос в совершенно свободной форме на адрес support@orlovsoft.com с указанием электронного адреса, имени, рода деятельности и примерного периода использования программы. Указанная Вами информация необходима нам для генерирования файлов лицензии.
Триал период использования уточняется индивидуально. Общие ориентиры таковы:
  • Ориентировочный период использования для инженеров: две недели.
  • Ориентировочный период использования для студентов: одна неделя.

13
Что такое Timo Structural / Что такое Timo Structural
« : Октябрь 07, 2012, 09:50:12 pm »
Timo Structural - программа для Windows, выполняющая расчеты каркасных сооружений, то есть стержневых конструкций.
Возможности:
  • Расчет всех внутренних силовых факторов, таких как внутренние продольные силы, поперечные силы, внутренние изгибающие моменты и момент кручения;
  • Расчет реакций - сосредоточенных сил и моментов;
  • Расчет перемещений в конструкции.

Особенности:
  • Главной концептуальной особенностью программы является т.н. показатель юсабилити, то есть легкость ее освоения. Так, монтаж конструкции осуществляется простым нажатием кнопок присоединения одного элемента - стержня к другому. Довольно серьезные сооружения моделируются втечение нескольких минут, а порог вхождения (время от первого старта до профессионального использования) измеряется 15-20 минутами. Такая технология реализована в виде интерактивного 3D редактора создания конструкций.
  • Timo Structural текущей версии не включает разного рода библиотек профилей, полагаясь на введеную пользователем информацию о характеристиках сечения, таких как осевые моменты инерции, модуль Юнга, модуль сдвига, площадь поперечного сечения, а также моменты сопротивления сечений для расчета основных напряжений. В этом преимущество программы, с одной стороны, и ее недостаток, с другой.
  • Решатель системы построен на основе системы компьютерной алгебры Wolfram Mathematica, что обеспечивает высочайшую надежность вычислений и предполагает использование самых эффективных алгоритмов.

Если в Вашем браузере установлен плагин Silverlight, то Вы можете взглянуть на скриншоты программы здесь
Скриншоты Silverlight
Если Вы не используете Silverlight, то Вы можете взглянуть на скриншоты программы здесь
Скриншоты
 

14
Администратор / Что и зачем?
« : Октябрь 07, 2012, 08:48:17 pm »
Добро пожаловать на форум русскоязычной поддержки продуктов Orlovsoft.

Текущие версии продуктов:
  • Timo Structural 1.01
  • Mechanics of Materials Toolbox for Maple v2.06
  • Timik 2.0 Online Helper. Beta
  • Timik Mobile

В качестве дополнения работает ветка для энтузиастов программирования на платформе WPF.

Важно. Сообщения, не соответствующие прямо или косвенно тематике сообщества, будут удаляться субъективным решением администраторов/модераторов.
Спасибо и еще раз Добро пожаловать!

Страницы: [1]