Многостраничные приложения в Silverlight - Более практичное использование
ОГЛАВЛЕНИЕ
Более практичное использование
Теперь, когда у нас есть основная архитектура, нам остается всего лишь создать полезные страницы для переключения. Как уже обсуждалось, мы создадим три страницы - первая будет генерировать список слов, которые будут использовать другие две.
Начнем с создания нового решения PageSwitching. Как только это будет открыто в Visual Studio, скопируйте файлы App.xaml.cs, ISwitchable.cs, PageSwitcher.xaml, PageSwitcher.xaml.cs и Switcher.cs из PageSwitch в новую директорию.
App.xaml.cs перепишет тот файл, что был создан Visual Studio (убедитесь в том, что вы настроили пространство имен файла), все остальные файлы будут новыми, и потому вам надо будет добавить их в ваш проект щелкнув правой кнопкой мыши по нему в Solution Explorer и выбрав пункт добавления нового элемента (Add Existing Item),
Рисунок 8-6. Добавление существующих элементов
Удалите Page.xaml и Page.xaml.cs и добавьте три новых UserControls: Find, Search и Count. Вот что у вас должно получиться после всего этого :
Рисунок 8-7. Проект PageSwitching
Давайте добавим внешний вид для страницы Find - первая страница, используемая для создания списка слов.
Вот Xaml, который я использовал для создания внешнего вида файла, но вы можете создать свой,
<UserControl x:Class="PageSwitching.Find"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="500" Height="600">
<Grid
x:Name="LayoutRoot"
Background="White">
<Grid.RowDefinitions>
<RowDefinition
Height="0.078*" />
<RowDefinition Height="0.072*"/>
<RowDefinition
Height="0.85*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="0.5*" />
<ColumnDefinition
Width="0.5*" />
</Grid.ColumnDefinitions>
<TextBlock
x:Name="Message"
Text="Ready..."
TextWrapping="Wrap"
FontFamily="Georgia"
FontSize="18"
VerticalAlignment="Bottom"
HorizontalAlignment="Left"
Visibility="Visible" Grid.Row="1" />
<ScrollViewer
x:Name="WordDisplayViewer"
BorderBrush="Black"
BorderThickness="1"
Grid.Row="2"
Grid.Column="0"
Margin="5,10,0,2"
Background="Bisque"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Hidden"
VerticalAlignment="Stretch"
Width="240"
HorizontalAlignment="Left"
Visibility="Visible">
<TextBlock
x:Name="WordDisplay"
TextWrapping="Wrap"
Text="WordDisplay"
Width="160" />
</ScrollViewer>
<ScrollViewer
x:Name="SortDisplayViewer"
BorderBrush="Black"
BorderThickness="1"
Grid.Row="2"
Grid.Column="1"
Margin="0,10,8,0"
Width="240"
Background="Wheat"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Hidden"
VerticalAlignment="Stretch"
HorizontalAlignment="Right"
Visibility="Visible">
<TextBlock
x:Name="SortDisplay"
TextWrapping="Wrap"
Width="160"
Text="SortDisplay" />
</ScrollViewer>
<StackPanel
Height="Auto"
VerticalAlignment="Stretch"
Grid.Column="1"
Orientation="Horizontal" Grid.RowSpan="2">
<Button
x:Name="FilePicker"
Content="Pick a file"
Width="100"
Background="#FF00FF00"
FontFamily="Georgia"
FontSize="18"
Height="35" HorizontalAlignment="Center"
VerticalAlignment="Center" />
<Grid Height="Auto" x:Name="ButtonGrid" Width="153">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<Button
x:Name="SearchPage"
Content="Search"
Background="#FFFF0000"
FontFamily="Georgia"
FontSize="18"
Margin="5,0,5,0"
Visibility="Visible"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.ColumnSpan="1"
Grid.RowSpan="2" />
<Button
x:Name="CountPage"
Content="Count"
Background="#FFFF0000"
FontFamily="Georgia"
FontSize="18"
Visibility="Visible"
VerticalAlignment="Center"
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Center"
Grid.RowSpan="2" />
</Grid>
</StackPanel>
</Grid>
</UserControl>
Вот как это выглядит
Рисунок 8-8. Поиск страницы
Find.xaml.cs должен реализовывать обработчики событий трех кнопок,
public Find()
{
InitializeComponent();
FilePicker.Click += new RoutedEventHandler( FilePicker_Click );
SearchPage.Click += new RoutedEventHandler( ChangePage );
CountPage.Click +=new RoutedEventHandler( ChangePage );
Обратите внимание на то, что кнопки SearchPage и CountPage имеют общий обработчик события потому, что их реализация очень схожа,
void ChangePage( object sender, RoutedEventArgs e )
{
Button b = e.OriginalSource as Button;
string btnName = b.Content.ToString().ToUpper();
if ( btnName == "SEARCH" )
Switcher.Switch( new SearchPage(), SortedWords );
else
Switcher.Switch( new CountPage(), SortedWords );
}
Логика здесь заключается в преобразовании свойства OriginalSource, принадлежащего Event Argument, в тип Button, и затем использовании для того, чтобы извлечь верхний регистр из содержимого кнопки. Мы затем сравниваем это со словом при поиске, и если они совпадут - мы вызываем метод Switch для страницы SearchPage (либо для CountPage) и передаем SortedWords, который является набором слов, необходимых для новой страницы.
Мы собираем данные слова путем прохода по большому документу и выдергивая все уникальные слова из него. Вы можете взять любой текстовый файл и положить его в соответствующий каталог на диске. Когда пользователь нажмет на кнопку выбора файла (Pick A File), обработчик события откроет диалоговое окно и попросит выбрать файл,
void FilePicker_Click( object sender, RoutedEventArgs e )
{
FilePicker.IsEnabled = false;
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files (.txt)|*.txt|All Files (*.*)|*.*";
openFileDialog1.FilterIndex = 1;
openFileDialog1.Multiselect = false;
bool? userClickedOK = openFileDialog1.ShowDialog();
Если пользователь нажмет на файл и затем кнопку OK - значение логической переменной userClickedOK будет равно true. На данном этапе вам нужно открыть streamReader по отношению к файлу для того, чтобы считать его содержимое в StringBuilder, прочитав все до конца файла, и добавляя каждую строку в ваш StringBuilder,
if ( userClickedOK == true )
{
// Ограничение количества считываемого
const long MAXBYTES = 2000; // 200000
System.IO.FileInfo file = openFileDialog1.File;
StringBuilder sb = new StringBuilder();
if ( file != null )
{
System.IO.Stream fileStream = file.OpenRead();
using ( System.IO.StreamReader reader =
new System.IO.StreamReader( fileStream ) )
{
string temp = string.Empty;
// соединение со строкой, пока у вас есть что считать
// и вы не дошли до лимита MAXBYTES
try
{
do
{
temp = reader.ReadLine();
sb.Append( temp );
} while ( temp != null && sb.Length < MAXBYTES );
}
catch { } // пока мы игнорируем исключительные ситуации
}
fileStream.Close(); // прибираем за собой (здесь должен быть блок finally)
}