Локализация 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, там же много ссылок на примеры использования этой библиотеки, исходники не выложены.

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

ссылка на оригинал статьи http://habrahabr.ru/post/206962/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *