UWP Community Toolkitを使ってみた
先日MSが、こんなライブラリを公開してました。
てことで、さっそく使ってみました。
概要・UWP Community Toolkitとは
MS製のUWP向けライブラリです。
アプリ作成の上でのフレームワークなどではなく、純粋なコントロール類や便利な各種ヘルパークラスなどが主な内容となっています。
各種機能も、数行のコードを書くだけで簡単に利用できるように作られていて、お気軽に使えます。
また、このライブラリを使うことで、アプリ全体をこう書かなきゃみたいな強制が無いので、その点でも非常に取り回しのよいライブラリだと思います。
ちなみに、MSはこのライブラリへのフィードバックを今後のWin10のSDKへと反映していくつもり、とのことです。
このライブラリで特に有用で安定してきた機能は、将来SDKに標準で取り込まれるかもしれません。
公式のサンプルアプリ
このライブラリでできることを簡単に体験できるよう、サンプルアプリが公開されてます。
https://www.microsoft.com/ja-jp/store/p/uwp-community-toolkit-sample-app/9nblggh4tlcq
まずは、ストアから以下のアプリをインストールして試してみるとよいかと。
UWP Community Toolkitでできることが一通りサンプルとして提供されています。
このアプリからコードのコピペなどもできるようになっています。
ライブラリの動作を見てみるだけでなく、開発時にコードスニペットの取得元、みたいな位置づけとしても便利かもしれません。
ロードマップ
今後のアップデートについては、以下のように書かれています。
https://github.com/Microsoft/UWPCommunityToolkit/issues?q=is%3Aopen+is%3Aissue+milestone%3Av1.1
https://github.com/Microsoft/UWPCommunityToolkit/milestones
月に一回くらいのアップデートを計画しているようですね。
準備
UWP Community Toolkitを使うには、以下の環境が必要です。
- Visual Studio 2015 with Update3
- Windows 10 SDK
VS2015をUpdate3にしてない場合は、まずアップデートしておきましょう。
ライブラリのインストール
インストールはNugetから行えるようになっています。
UWP Community Toolkitでは、機能ごとに複数のアセンブリに分かれています。
アセンブリ一覧は↓のページにまとまっています。
https://developer.microsoft.com/en-us/windows/uwp-community-toolkit/nugetpackages
自分が必要な機能のアセンブリを適宜取得していく、という感じで使います。
これらのアセンブリは、NugetのGUIからMicrosoft.Toolkit.UWP
で検索すると出てきます。
ここから探せば、目的のものをすぐ見つけられるかと。
使ってみる
ということで、さっそく使ってみます。
細かいことは、公式リポジトリのリンクからリファレンスを読むとよいですが、 ここでは特に便利そうと感じた、主な機能/コントロールの使い方をまとめてみます。
Control類
まずは、各種コントロール類から。
ハンバーガーメニューを作るコントロールをはじめ、sdkに標準で入れておいてほしいような便利なコントロールが多数用意されています。
この辺のコントロール類を使うときは、Microsoft.Toolkit.Uwp.UI.Controls
というパッケージをインストールします。
Nugetパッケージマネージャ コンソールから、以下のコマンドでインストールできます。
Install-Package Microsoft.Toolkit.Uwp.UI.Controls
HeaderedTextBlock
項目のタイトルを表示することができるようになっているテキストブロックです。 これはコードだけ見ればなんとなく使えるかと。
<StackPanel> <controls:HeaderedTextBlock Margin="5" Header="Name" Text="UWP Toolkit" /> <controls:HeaderedTextBlock Margin="5" Header="Title" Orientation="Horizontal" Text="ここに内容を書く" /> </StackPanel>
プロパティ名 | 内容 |
---|---|
Header | 項目のヘッダーを設定 |
Text | 項目の本文を設定 |
Orientation | ヘッダーと本文の並ぶ方向を設定 |
RangeSelector
普通のスライダーと違い、下限値/上限値の二つを設定できるようになっているものです。
こういうコントロール、確かに微妙にほしくなる時ありますよね。
<controls:RangeSelector Maximum="100" Minimum="10" RangeMax="50" RangeMin="30" />
プロパティ名 | 内容 |
---|---|
Maximum | 現在の設定値(上限側)を設定 |
Minimum | 現在の設定値(下限側)を設定 |
RangeMax | 設定可能な値の最大値を設定(スライダーの右端の値) |
RangeMin | 設定可能な値の最小値を設定(スライダーの左端の値) |
AdaptiveGrid
これは結構使いどころの多そうなコントロール。
画像のサムネイル一覧とか表示するときに便利そうです。
こんな風に、各グリッドの幅がDesiredWidth以上になるように保った上で、入るだけ列を作ってAdaptiveGridの幅いっぱいに埋める、って感じの動作です。
MainPage.xaml
<Page.Resources> <DataTemplate x:Key="PhotosTemplate"> <Grid Background="White" BorderBrush="Black" BorderThickness="1"> <Image HorizontalAlignment="Center" VerticalAlignment="Center" Source="{Binding}" Stretch="UniformToFill" /> </Grid> </DataTemplate> </Page.Resources> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <controls:AdaptiveGridView Margin="5" DesiredWidth="300" ItemHeight="200" ItemTemplate="{StaticResource PhotosTemplate}" ItemsSource="{x:Bind ImageList}" /> </Grid>
MainPage.xaml.cs
public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); this.ImageList = new List<string>() { "Images/1.JPG", "Images/2.JPG", "Images/3.JPG", "Images/4.JPG", "Images/5.JPG", "Images/6.JPG", }; } public IList<string> ImageList { get; set; } }
プロパティ名 | 内容 |
---|---|
DesiredWidth | 各グリッドの最小幅のサイズを設定 |
ItemHeight | 各グリッドの高さを設定 |
OneRowModeEnabled | trueにすると、1行だけ表示するようになります。 |
ItemsSource | グリッドに表示する要素のリストを設定 |
ItemTemplate | グリッドに表示する各アイテムのテンプレートを設定 |
ItemClickCommand | 各要素をクリックした際に呼び出されるコマンドを設定 |
イベント名 | 内容 |
---|---|
ItemClick | 各要素をクリックした際に発生するイベント |
SlidableListItem
横フリックで要素の選択などができるコントロールです。
ListBoxやListViewなどのItemTemplateとして使い、リストの各要素のテンプレートとして使うことを想定されたコントロールです。
スマホ向けのUIとかで、結構便利に使えそうですね。
MainPage.xaml
<Page.Resources> <DataTemplate x:Key="EmailsItemTemplate"> <controls:SlidableListItem MinWidth="300" MaxWidth="800" HorizontalAlignment="Stretch" LeftIcon="Message" LeftLabel="ダイアログを表示" LeftCommandRequested="SlidableListItem_LeftCommandActivated" RightIcon="Delete" RightLabel="削除します" RightCommandRequested="SlidableListItem_RightCommandActivated" MouseSlidingEnabled="True"> <Grid Height="110" Background="WhiteSmoke"> <TextBlock Grid.Column="1" Margin="12" VerticalAlignment="Center" FontSize="16" FontWeight="Light" Text="{Binding}" TextWrapping="NoWrap" /> </Grid> </controls:SlidableListItem> </DataTemplate> </Page.Resources> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <ListView x:Name="listView" HorizontalAlignment="Center" IsItemClickEnabled="False" ItemTemplate="{StaticResource EmailsItemTemplate}" ItemsSource="{x:Bind ImageList, Mode=OneWay}" SelectionMode="None"> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="Margin" Value="0,1" /> </Style> </ListView.ItemContainerStyle> </ListView> </Grid>
MainPage.xaml.cs
public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); this.ImageList = new ObservableCollection<string>() { "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", }; } public ObservableCollection<string> ImageList { get; set; } private async void SlidableListItem_LeftCommandActivated(object sender, EventArgs e) { var item = (sender as SlidableListItem).DataContext as string; var dlg = new Windows.UI.Popups.MessageDialog(item); await dlg.ShowAsync(); } private void SlidableListItem_RightCommandActivated(object sender, EventArgs e) { ImageList.Remove((sender as SlidableListItem).DataContext as string); } }
HamburgerMenu
名前の通り、ハンバーガーメニューを作るためのコントロール。 このコントロールを使うと、簡単にハンバーガーメニューを伴ったUIを実装できます。
ここでのサンプルでは、選択した画像を表示しているだけですが、HamburgerMenu内部にFrameコントロールを配置してページ切替できるようにすると、よく見かける感じのUIになるかと思います。
MainPage.xaml
<Page.Resources> <DataTemplate x:Key="DefaultTemplate" x:DataType="local:MenuItem"> <Grid Width="240" Height="48"> <Grid.ColumnDefinitions> <ColumnDefinition Width="48" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Image Margin="3" Source="{x:Bind ImagePath}" Stretch="UniformToFill" /> <TextBlock Grid.Column="1" VerticalAlignment="Center" FontSize="16" Foreground="White" Text="{x:Bind Title, Mode=OneWay}" /> </Grid> </DataTemplate> </Page.Resources> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <controls:HamburgerMenu x:Name="hamburgerMenuControl" Foreground="White" ItemClick="OnMenuItemClick" ItemTemplate="{StaticResource DefaultTemplate}" ItemsSource="{x:Bind List}" OptionsItemTemplate="{StaticResource DefaultTemplate}" PaneBackground="Black"> <Image x:Name="imgSelected" Margin="10" /> </controls:HamburgerMenu> </Grid>
MainPage.xaml.cs
public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); this.List = new ObservableCollection<MenuItem>() { new MenuItem("Sample1", "Images/1.JPG"), new MenuItem("Sample2", "Images/2.JPG"), new MenuItem("Sample3", "Images/3.JPG"), new MenuItem("Sample4", "Images/4.JPG"), new MenuItem("Sample5", "Images/5.JPG"), new MenuItem("Sample6", "Images/6.JPG"), }; } public ObservableCollection<MenuItem> List { get; set; } private void OnMenuItemClick(object sender, ItemClickEventArgs e) { var clicked = e.ClickedItem as MenuItem; this.imgSelected.Source = new BitmapImage(new Uri($"ms-appx://UwpToolkitTest/{clicked.ImagePath}")); } } public class MenuItem { public string Title { get; set; } public string ImagePath { get; set; } public MenuItem(string title, string path) { this.Title = title; this.ImagePath = path; } }
RadialGauge
これは、使いどころを選びそうなコントロールですね。
車の速度計みたいな表示のコントロールです。
<StackPanel> <controls:RadialGauge Grid.Column="1" Value="{Binding ElementName=slider, Path=Value}" Minimum="0" Maximum="180" TickSpacing="20" ScaleWidth="26" Unit="Units" TickBrush="Gainsboro" ScaleTickBrush="{ThemeResource ApplicationPageBackgroundThemeBrush}" UnitBrush="Black" ValueBrush="Black" NeedleWidth="5" TickLength="18" /> <Slider x:Name="slider" Margin="10" Minimum="0" Maximum="180"/> </StackPanel>
Animations
アニメーション効果を簡単に加えるためのクラス類です。
コードビハインドから呼ぶことも、xaml上からビヘイビアとして設定することもできます。
それぞれの使い方を順番に見ていきます。
コードビハインドからのアニメーション
Blur
、Offset
、Fade
、Rotate
、Scale
といったアニメーション用の拡張メソッドが用意されています。
using Microsoft.Toolkit.Uwp.UI.Animations;
という名前空間の設定を加えると、
以下のように、FrameworkElementやUIElementのようなUI要素に対して、これらのアニメーション用の拡張メソッドが呼び出せるようになります。
MainPage.xaml
<Border x:Name="border" Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" Background="LightGray" BorderBrush="Black" BorderThickness="1" Padding="10"> <FontIcon FontFamily="Segoe MDL2 Assets" FontSize="128" Glyph="" /> </Border> <Button Margin="10,165,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Content="Button" Click="Button_Click" />
MainPage.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e) { this.border.Blur(value: 10, duration: 100, delay: 100) .StartAsync(); }
メソッドチェーンでつなぐ
以下のようにメソッドチェーンで複数のアニメーションをつなぎ、順次実行することもできます。
private void Button_Click(object sender, RoutedEventArgs e) { this.border.Blur(value: 10, duration: 500) .Offset(offsetX: 50, offsetY: 100, delay: 500) .Rotate(value: 60, duration: 500, delay: 1000) .StartAsync(); }
ビヘイビアを用いたアニメーション
以下のように、ビヘイビアとしてこれらのアニメーションを定義することもできます。
<Border Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" Background="LightGray" BorderBrush="Black" BorderThickness="1" Padding="10"> <interactivity:Interaction.Behaviors> <behaviors:Blur x:Name="BlurBehavior" AutomaticallyStart="False" Delay="100" Duration="1000" Value="10" /> </interactivity:Interaction.Behaviors> <FontIcon FontFamily="Segoe MDL2 Assets" FontSize="128" Glyph="" /> </Border> <Button Margin="10,165,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Content="Button"> <interactivity:Interaction.Behaviors> <core:EventTriggerBehavior EventName="Click"> <core:CallMethodAction MethodName="StartAnimation" TargetObject="{Binding ElementName=BlurBehavior}" /> </core:EventTriggerBehavior> </interactivity:Interaction.Behaviors> </Button>
各種Helperなど
コンバーターやちょっとしたユーティリティクラスなども用意されています。
color
RGBではなく、HSV表色系で色を表す、HsvColor構造体などが用意されています。
また、HSV値や16進数文字列のRGB値などからColor構造体を作るためのヘルパークラスなどなど、色を扱う上で便利な機能が用意されてます。
var hsv = new HsvColor(); hsv.H = 180; var col1 = ColorHelper.FromHsv(180, 0.5, 0.5); var col2 = ColorHelper.ToColor("Red"); var col3 = ColorHelper.ToColor("#FF00FF");
コンバーター類
以下のようなコンバーターが用意されています。
使用する場合は、xamlで以下のような名前空間の設定をしておきます。
xmlns:Converters="using:Microsoft.Toolkit.Uwp.UI.Converters"
名前 | 内容 |
---|---|
BoolToVisibilityConverter | bool値をVisibilityに変換 |
CollectionVisibilityConverter | コレクションの要素が0個の場合、Visibility.Collapsedに変換するコンバーター |
StringFormatConverter | ConverterParameterで指定した書式で文字列をフォーマットして返すコンバーター |
StringVisibilityConverter | 文字列がnullまたは空文字の場合に、Visibility.Collapsedに変換するコンバーター |
UWPではBooleanToVisibilityConverterが標準ではなくて何かと不便ですが、そんな時にはここで用意されているBoolToVisibilityConverterが使えます。
外部サービスとの連携
BingやTwitter, Facebookといった、定番どころのWebServiceとの連携を簡単に行うための各種ヘルパークラスも用意されています。
こんな風に簡単にBing検索結果を利用したりすることができます。
Microsoft.Toolkit.Uwp.Services
というパッケージをNugetでインストールして、以下のように使います。
<Page x:Class="UwpToolkitTest.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:bing="using:Microsoft.Toolkit.Uwp.Services.Bing" xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:core="using:Microsoft.Xaml.Interactions.Core" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:UwpToolkitTest" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <DataTemplate x:Key="SearchResultTemplate" x:DataType="bing:BingResult"> <Grid Margin="0,5,10,5"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" FontWeight="Bold" Text="{x:Bind Title}" TextTrimming="CharacterEllipsis" /> <TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Text="{x:Bind Published}" /> <TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Text="{x:Bind Summary}" TextWrapping="Wrap" /> <HyperlinkButton Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Bind Link}" NavigateUri="{x:Bind Link}" /> </Grid> </DataTemplate> </Page.Resources> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <TextBox x:Name="txtKerword" Width="250" Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" Text="Windows 10" TextWrapping="Wrap" /> <Button Margin="265,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click" Content="検索" /> <ListView x:Name="lstResult" Grid.Row="1" Margin="10" ItemTemplate="{StaticResource SearchResultTemplate}" /> </Grid> </Page>
private async void Button_Click(object sender, RoutedEventArgs e) { var searchConfig = new BingSearchConfig { Country = BingCountry.Japan, Query = this.txtKerword.Text }; this.lstResult.ItemsSource = await BingService.Instance.RequestAsync(searchConfig, 50); }