...

воскресенье, 22 декабря 2013 г.

[Из песочницы] Локализация ApplicationBar с помощью Binding

Когда я учился разрабатывать приложения на основе MVVM мне жутко не понравилось, что во многих статьях показано как ApplicationBar создается во ViewModel. Там же кнопки и элементы меню заполняется локализованными строками. Я долго искал решение, и оно было найдено.

Внимание! Статья описывает только решение проблемы локализации панели приложения и подразумевает что читатели знакомы с основами XAML, MVVM, связыванием данных и локализацией приложений.



Встречайте бибилиотеку для локализации панели приложения: http://appbarutils.codeplex.com/

Что бы попробовать ее в работе создадим страницу приложения и добавим в ней обычную панель приложения, с кнопками и, если необходимо, пунктами меню. Например, такую:

<shell:ApplicationBar>
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem IsEnabled="True" Text="lookscreen"/>
</shell:ApplicationBar.MenuItems>
<shell:ApplicationBarIconButton IconUri="/Assets/AppBar/save.png" IsEnabled="True" Text="save"/>
</shell:ApplicationBar>




Обратите внимание: свойство Text должно быть без пробелов. Работоспособность при наличии кириллицы не проверял.

Добавляем пакет AppBarUtils в приложение командой Install-Package AppBarUtils или через диспетчер пакетов. Добавляем в разметку страницы ссылку на сборку этого пакета:

xmlns:AppBarUtils="clr-namespace:AppBarUtils;assembly=AppBarUtils"




И нам еще понадобится сборка для задания поведений:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"




После этих приготовлений задаем поведения для страницы на которой находится панель приложения. У меня получилось вот так:

<i:Interaction.Behaviors>
<AppBarUtils:AppBarItemCommand Id="save" Type="Button" Command="{Binding SaveCommand}" Text="{Binding LocalizedResources.SaveButton, Mode=OneWay, Source={StaticResource LocalizedStrings}}"/>
<AppBarUtils:AppBarItemCommand Id="lookscreen" Type="MenuItem" Command="{Binding LookScreenCommand}" Text="{Binding LocalizedResources.ScreenItem, Mode=OneWay, Source={StaticResource LocalizedStrings}}"/>
</i:Interaction.Behaviors>




Связывание поведения с элементом, которому он назначен, происходит по ID со значением равным свойству Text пункта меню или кнопки. Кроме того, задается тип элемента меню, которому задается поведение: для кнопки – Button, для пункта меню – MenuItem. Значение остальных свойств пояснять думаю не нужно.

После всех манипуляций у меня получилась страница в реальном приложении, которое опубликовано в windows phone store:

XAML


<phone:PhoneApplicationPage
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"
xmlns:AppBarUtils="clr-namespace:AppBarUtils;assembly=AppBarUtils"
x:Class="CatDay.MainPage"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations ="PortraitOrLandscape"
shell:SystemTray.IsVisible="True"
DataContext="{Binding Main, Mode=OneWay, Source={StaticResource Locator}}">
<shell:SystemTray.ProgressIndicator>
<shell:ProgressIndicator IsIndeterminate="true" IsVisible="{Binding ProgressBarValue}" Text="{Binding ProgressBarText}" />
</shell:SystemTray.ProgressIndicator>


<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar>
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem IsEnabled="True" Text="donate"/>
<shell:ApplicationBarMenuItem IsEnabled="True" Text="lookscreen"/>
<shell:ApplicationBarMenuItem IsEnabled="True" Text="skydrive"/>
<shell:ApplicationBarMenuItem IsEnabled="True" Text="feedback"/>
</shell:ApplicationBar.MenuItems>
<shell:ApplicationBarIconButton IconUri="/Assets/AppBar/transport.rew.png" IsEnabled="True" Text="previus"/>
<shell:ApplicationBarIconButton IconUri="/Assets/AppBar/save.png" IsEnabled="True" Text="save"/>
<shell:ApplicationBarIconButton IconUri="/Assets/AppBar/share.png" IsEnabled="True" Text="share"/>
<shell:ApplicationBarIconButton IconUri="/Assets/AppBar/transport.ff.png" IsEnabled="True" Text="next"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

<i:Interaction.Behaviors>
<AppBarUtils:AppBarItemCommand Id="next" Type="Button" Text="{Binding LocalizedResources.NextButton, Mode=OneWay, Source={StaticResource LocalizedStrings}}" Command="{Binding NextImageCommand}"/>
<AppBarUtils:AppBarItemCommand Id="share" Type="Button" Command="{Binding ShareCommand}" Text="{Binding LocalizedResources.ShareButton, Mode=OneWay, Source={StaticResource LocalizedStrings}}"/>
<AppBarUtils:AppBarItemCommand Id="previus" Type="Button" Command="{Binding PreviusImageCommand}" Text="{Binding LocalizedResources.PreviusButton, Mode=OneWay, Source={StaticResource LocalizedStrings}}"/>
<AppBarUtils:AppBarItemCommand Id="save" Type="Button" Command="{Binding SaveCommand}" Text="{Binding LocalizedResources.SaveButton, Mode=OneWay, Source={StaticResource LocalizedStrings}}"/>
<AppBarUtils:AppBarItemCommand Id="lookscreen" Type="MenuItem" Command="{Binding LookScreenCommand}" Text="{Binding LocalizedResources.ScreenItem, Mode=OneWay, Source={StaticResource LocalizedStrings}}"/>
<AppBarUtils:AppBarItemCommand Id="skydrive" Type="MenuItem" Command="{Binding SkyDriveCommand}" Text="{Binding LocalizedResources.SkydriveItem, Mode=OneWay, Source={StaticResource LocalizedStrings}}" />
<AppBarUtils:AppBarItemCommand Id="donate" Type="MenuItem" Text="{Binding LocalizedResources.DonateMenuItem, Mode=OneWay, Source={StaticResource LocalizedStrings}}" Command="{Binding DonateCommand }"/>
<AppBarUtils:AppBarItemCommand Id="feedback" Type="MenuItem" Text="{Binding LocalizedResources.FeedbackAppBarButton, Mode=OneWay, Source={StaticResource LocalizedStrings}}" Command="{Binding FeedbackCommand}"/>
</i:Interaction.Behaviors>

<!--LayoutRoot представляет корневую сетку, где размещается все содержимое страницы-->
<Grid x:Name="LayoutRoot" Background="Transparent">

<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="{Binding LocalizedResources.ApplicationTitle, Mode=OneWay, Source={StaticResource LocalizedStrings}}" Style="{StaticResource PhoneTextGroupHeaderStyle}" Margin="12,0"/>
</StackPanel>
</Grid>
</phone:PhoneApplicationPage>






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


Надеюсь, что эта маленькая статья поможет начинающим разработчикам в локализации приложений, а опытных разработчиков избавит от распространенного заблуждения что панель приложения нельзя локализовать с помощью связывания данных.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers.


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

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