[UWPアプリ][Grid] 子要素の配置

前回の[UWPアプリ][Grid] 行と列を作成するで、行と列の作成方法を紹介しました。

今回は、Gridに作成した行と列に子要素を配置する方法を見ていきましょう。

Gridに行と列を作成すると、番号で管理できるようになります。

2行2列の場合は下図のようになります。

2行2列のグリッド

Mainpage.xamlに配置されているGridを3行3列に分割して、以下のように真ん中のセルにボタンを配置する方法を見ていきましょう。

Gridへのボタン配置

Gridを3行3列に分割するXamlは以下の通りです。

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="100" />
        <RowDefinition Height="100" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="300"/>
        <ColumnDefinition Width="300"/>
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
</Grid>

続いてButtonを2行目2列目の位置に配置するXamlを見てみましょう。

<Button x:Name="button" Content="Button" FontSize="48"
        Width="300" Height="100"
        Grid.Column="1" Grid.Row="1" />

Buttonのコードを見ると Grid.Column=”1″ とGrid.Row=”1″があることがわかります。

このように、Gridの子要素となったコントロールはGrid.ColumnとGrid.Rowで配置位置を設定できるようになります。このような属性を添付プロパティと呼びます。

Grid.ColumnとGrid.Rowの位置は0から数えます。よって2行2列の位置へ設定する場合はGrid.Column=”1″ Grid.Row=”1″となります。

 

[CodeZine] WPF/Silverlightで使える逆引きTips集 インクキャンバス機能編

翔泳社さんの CodeZine のサイトにて「WPF/Silverlightで使える逆引きTips集 インクキャンバス機能編」が公開されました。

今回は WPF オンリーのTips となります。

これまでの連載は下記の通りです。

WPF の開発をされている方、是非ご覧ください。

[Silverlight] AutoComplete コントロールのテンプレート

Explession Blend をお持ちの方はコントロールのテンプレートを取得/編集が容易なのですが、Visual Studioしか持っていない場合はテンプレートを編集する作業は大変です。

そこで、今回は Silverlight で使用できる AutoComplete コントロールのテンプレートを紹介します。(Expression Blend 4を使用して抜き出したものです)

<UserControl.Resources>
	<ControlTemplate x:Key="CommonValidationToolTipTemplate" TargetType="ToolTip">
		<Grid x:Name="Root" Margin="5,0" Opacity="0" RenderTransformOrigin="0,0">
			<Grid.RenderTransform>
				<TranslateTransform x:Name="Translation" X="-25"/>
			</Grid.RenderTransform>
			<VisualStateManager.VisualStateGroups>
				<VisualStateGroup x:Name="OpenStates">
					<VisualStateGroup.Transitions>
						<VisualTransition GeneratedDuration="0"/>
						<VisualTransition GeneratedDuration="0:0:0.2" To="Open">
							<Storyboard>
								<DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="Translation">
									<DoubleAnimation.EasingFunction>
										<BackEase Amplitude=".3" EasingMode="EaseOut"/>
									</DoubleAnimation.EasingFunction>
								</DoubleAnimation>
								<DoubleAnimation Duration="0:0:0.2" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
							</Storyboard>
						</VisualTransition>
					</VisualStateGroup.Transitions>
					<VisualState x:Name="Closed">
						<Storyboard>
							<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
						</Storyboard>
					</VisualState>
					<VisualState x:Name="Open">
						<Storyboard>
							<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="Translation"/>
							<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
						</Storyboard>
					</VisualState>
				</VisualStateGroup>
			</VisualStateManager.VisualStateGroups>
			<Border Background="#052A2E31" CornerRadius="5" Margin="4,4,-4,-4"/>
			<Border Background="#152A2E31" CornerRadius="4" Margin="3,3,-3,-3"/>
			<Border Background="#252A2E31" CornerRadius="3" Margin="2,2,-2,-2"/>
			<Border Background="#352A2E31" CornerRadius="2" Margin="1,1,-1,-1"/>
			<Border Background="#FFDC000C" CornerRadius="2">
				<TextBlock Foreground="White" MaxWidth="250" Margin="8,4,8,4" TextWrapping="Wrap" Text="{Binding (Validation.Errors)[0].ErrorContent}" UseLayoutRounding="false"/>
			</Border>
		</Grid>
	</ControlTemplate>
	<Style x:Key="AutoCompleteBoxStyle1" TargetType="sdk:AutoCompleteBox">
		<Setter Property="IsTabStop" Value="False"/>
		<Setter Property="Padding" Value="2"/>
		<Setter Property="BorderThickness" Value="1"/>
		<Setter Property="BorderBrush">
			<Setter.Value>
				<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
					<GradientStop Color="#FFA3AEB9" Offset="0"/>
					<GradientStop Color="#FF8399A9" Offset="0.375"/>
					<GradientStop Color="#FF718597" Offset="0.375"/>
					<GradientStop Color="#FF617584" Offset="1"/>
				</LinearGradientBrush>
			</Setter.Value>
		</Setter>
		<Setter Property="Background" Value="#FFFFFFFF"/>
		<Setter Property="Foreground" Value="#FF000000"/>
		<Setter Property="MinWidth" Value="45"/>
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="sdk:AutoCompleteBox">
					<Grid Opacity="{TemplateBinding Opacity}">
						<VisualStateManager.VisualStateGroups>
							<VisualStateGroup x:Name="PopupStates">
								<VisualStateGroup.Transitions>
									<VisualTransition GeneratedDuration="0:0:0.1" To="PopupOpened"/>
									<VisualTransition GeneratedDuration="0:0:0.2" To="PopupClosed"/>
								</VisualStateGroup.Transitions>
								<VisualState x:Name="PopupOpened">
									<Storyboard>
										<DoubleAnimation To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PopupBorder"/>
									</Storyboard>
								</VisualState>
								<VisualState x:Name="PopupClosed">
									<Storyboard>
										<DoubleAnimation To="0.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PopupBorder"/>
									</Storyboard>
								</VisualState>
							</VisualStateGroup>
							<VisualStateGroup x:Name="ValidationStates">
								<VisualState x:Name="Valid"/>
								<VisualState x:Name="InvalidUnfocused">
									<Storyboard>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
											<DiscreteObjectKeyFrame KeyTime="0">
												<DiscreteObjectKeyFrame.Value>
													<Visibility>Visible</Visibility>
												</DiscreteObjectKeyFrame.Value>
											</DiscreteObjectKeyFrame>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
								<VisualState x:Name="InvalidFocused">
									<Storyboard>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
											<DiscreteObjectKeyFrame KeyTime="0">
												<DiscreteObjectKeyFrame.Value>
													<Visibility>Visible</Visibility>
												</DiscreteObjectKeyFrame.Value>
											</DiscreteObjectKeyFrame>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" Storyboard.TargetName="validationTooltip">
											<DiscreteObjectKeyFrame KeyTime="0">
												<DiscreteObjectKeyFrame.Value>
													<System:Boolean>True</System:Boolean>
												</DiscreteObjectKeyFrame.Value>
											</DiscreteObjectKeyFrame>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
							</VisualStateGroup>
						</VisualStateManager.VisualStateGroups>
						<TextBox x:Name="Text" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" IsTabStop="True" Margin="0" Padding="{TemplateBinding Padding}" Style="{TemplateBinding TextBoxStyle}"/>
						<Border x:Name="ValidationErrorElement" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1" Visibility="Collapsed">
							<ToolTipService.ToolTip>
								<ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource CommonValidationToolTipTemplate}">
									<ToolTip.Triggers>
										<EventTrigger RoutedEvent="Canvas.Loaded">
											<BeginStoryboard>
												<Storyboard>
													<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="validationTooltip">
														<DiscreteObjectKeyFrame KeyTime="0">
															<DiscreteObjectKeyFrame.Value>
																<System:Boolean>true</System:Boolean>
															</DiscreteObjectKeyFrame.Value>
														</DiscreteObjectKeyFrame>
													</ObjectAnimationUsingKeyFrames>
												</Storyboard>
											</BeginStoryboard>
										</EventTrigger>
									</ToolTip.Triggers>
								</ToolTip>
							</ToolTipService.ToolTip>
							<Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">
								<Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C" Margin="1,3,0,0"/>
								<Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff" Margin="1,3,0,0"/>
							</Grid>
						</Border>
						<Popup x:Name="Popup">
							<Grid Opacity="{TemplateBinding Opacity}">
								<Border x:Name="PopupBorder" BorderThickness="0" Background="#11000000" HorizontalAlignment="Stretch" Opacity="0">
									<Border.RenderTransform>
										<TranslateTransform X="1" Y="1"/>
									</Border.RenderTransform>
									<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0" HorizontalAlignment="Stretch" Opacity="1.0" Padding="0">
										<Border.Background>
											<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
												<GradientStop Color="#FFDDDDDD" Offset="0"/>
												<GradientStop Color="#AADDDDDD" Offset="1"/>
											</LinearGradientBrush>
										</Border.Background>
										<Border.RenderTransform>
											<TransformGroup>
												<TranslateTransform X="-1" Y="-1"/>
											</TransformGroup>
										</Border.RenderTransform>
										<ListBox x:Name="Selector" BorderThickness="0" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ItemTemplate="{TemplateBinding ItemTemplate}" ItemContainerStyle="{TemplateBinding ItemContainerStyle}" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
									</Border>
								</Border>
							</Grid>
						</Popup>
					</Grid>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
	</Style>
</UserControl.Resources>

ちなみに 過去にCodeZine にて AutoCompltete の Tips記事を執筆していますので、併せてご覧ください。
コントロールテンプレートを編集すれば、オリジナルのコントロールを容易に作成することができるので是非挑戦してみてください。
機会があれば、今回紹介したテンプレートのカスタマイズについて書きたいと思います。