IPhoneのようなスライドON/OFFスイッチの作成に関するWPFチュートリアルを探しています。
次に例を示します(「すべてのトラフィックを送信」オプション) https://secure-tunnel.com/support/software_setup/iphone/images/iphone_vpn_settings.jpg
何か案は?
乾杯、ケビン。
この問題に関するチュートリアルを見たことはありませんが、Expression Blendを起動してCheckBoxを配置することから始められると思います。次に、チェックボックスを選択し、メインメニュー-オブジェクト->スタイルの編集->コピーの編集に移動します
これにより、BlendはCheckBoxのデフォルトスタイルを生成するため、変更することができます。そこでどのように機能するかを見て、いくつかの結果を達成することができます。
基本的に(色やブラシ以外に)IsCheckedプロパティに接続されたトリガーを調べる必要があります。例えば。 IsCheckedがTrueの場合、長方形を辺の1つに移動し、ONワードを表示し、OFFワードを非表示にします。これをアニメーション化するには、トリガーのイン/アウトアニメーションを追加するだけです。
UPD:「プロトタイプ」を作成するために10〜15分を費やしました。
<Window
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
x:Class="CheckBoxIPhone.Window1"
x:Name="Window"
Title="Window1"
Width="320"
Height="240"
FontFamily="Segoe UI"
FontSize="20"
WindowStartupLocation="CenterScreen"
>
<Window.Resources>
<Style x:Key="CheckBoxStyle1" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<ControlTemplate.Resources>
<Storyboard x:Key="OnChecking">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="25"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnUnchecking">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(FrameworkElement.Margin)">
<SplineThicknessKeyFrame KeyTime="00:00:00.3000000" Value="1,1,1,1"/>
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<DockPanel x:Name="dockPanel">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" RecognizesAccessKey="True" VerticalAlignment="Center"/>
<Grid Margin="5,5,0,5" Width="50" Background="#FFC0CCD9">
<TextBlock Text="ON" TextWrapping="Wrap" FontWeight="Bold" FontSize="12" HorizontalAlignment="Right" Margin="0,0,3,0"/>
<TextBlock HorizontalAlignment="Left" Margin="2,0,0,0" FontSize="12" FontWeight="Bold" Text="OFF" TextWrapping="Wrap"/>
<Border HorizontalAlignment="Left" x:Name="slider" Width="23" BorderThickness="1,1,1,1" CornerRadius="3,3,3,3" RenderTransformOrigin="0.5,0.5" Margin="1,1,1,1">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Border.RenderTransform>
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#FF4490FF" Offset="1"/>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF8AB4FF" Offset="1"/>
<GradientStop Color="#FFD1E2FF" Offset="0"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource OnUnchecking}" x:Name="OnUnchecking_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource OnChecking}" x:Name="OnChecking_BeginStoryboard"/>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<CheckBox HorizontalAlignment="Center" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Center" Content="CheckBox"/>
</Grid>
</Window>
興味がある場合は、WPFのスタイルとテンプレートについて読むこともお勧めします。
オレンジとブルーのarconautの投稿に基づいて、いくつかのスタイルを作成しました。
スクリーンショット:
私のスタイルを、iOSデバイスのオン/オフスイッチスタイルに近づけたいと思いました。このスタイルの1つの違いは、スライドアニメーションはスイッチをスライドするだけで、下のインジケーターはスライドしないことです。たぶん私はいくつかの時間を見つけることができれば、私はそれをそのように変更します。それまでは、結果を共有したいと思います。完全ではありませんが、ここにコードがあります。
<LinearGradientBrush x:Key="CheckedBlue" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FF285AB3" Offset="0" />
<GradientStop Color="#FF4184EC" Offset="0.5" />
<GradientStop Color="#FF558BED" Offset="0.5" />
<GradientStop Color="#FF7DACF0" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="CheckedOrange" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFCA6A13" Offset="0" />
<GradientStop Color="#FFF67D0C" Offset="0.2" />
<GradientStop Color="#FFFE7F0C" Offset="0.2" />
<GradientStop Color="#FFFA8E12" Offset="0.5" />
<GradientStop Color="#FFFF981D" Offset="0.5" />
<GradientStop Color="#FFFCBC5A" Offset="1" />
</LinearGradientBrush>
<SolidColorBrush x:Key="CheckedOrangeBorder" Color="#FF8E4A1B" />
<SolidColorBrush x:Key="CheckedBlueBorder" Color="#FF143874" />
<Style x:Key="OrangeSwitchStyle" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<ControlTemplate.Resources>
<Storyboard x:Key="OnChecking">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="53" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnUnchecking">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<DockPanel x:Name="dockPanel">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" RecognizesAccessKey="True" VerticalAlignment="Center" />
<Grid>
<Border x:Name="BackgroundBorder" BorderBrush="#FF939393" BorderThickness="1" CornerRadius="3" Height="27" Width="94">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFB5B5B5" Offset="0" />
<GradientStop Color="#FFDEDEDE" Offset="0.1" />
<GradientStop Color="#FFEEEEEE" Offset="0.5" />
<GradientStop Color="#FFFAFAFA" Offset="0.5" />
<GradientStop Color="#FFFEFEFE" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition /><ColumnDefinition />
</Grid.ColumnDefinitions>
<Ellipse x:Name="Off" Width="14" Height="14" Stroke="#FF7A7A7A" StrokeThickness="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Line x:Name="On" X1="0" Y1="0" X2="0" Y2="14" Stroke="#FF7A7A7A" StrokeThickness="2" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>
<Border BorderBrush="#FF939393" HorizontalAlignment="Left" x:Name="slider" Width="41" Height="27" BorderThickness="1" CornerRadius="3" RenderTransformOrigin="0.5,0.5" Margin="0">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Border.RenderTransform>
<Border.Background>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFF0F0F0" Offset="0" />
<GradientStop Color="#FFCDCDCD" Offset="0.1" />
<GradientStop Color="#FFFBFBFB" Offset="1" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource OnUnchecking}" x:Name="OnUnchecking_BeginStoryboard" />
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource OnChecking}" x:Name="OnChecking_BeginStoryboard" />
</Trigger.EnterActions>
<Setter TargetName="On" Property="Stroke" Value="White" />
<Setter TargetName="Off" Property="Stroke" Value="White" />
<!-- Change Orange or Blue color here -->
<Setter TargetName="BackgroundBorder" Property="Background" Value="{StaticResource CheckedOrange}" />
<Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="{StaticResource CheckedOrangeBorder}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<!-- ToDo: Add Style for Isenabled == False -->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
いくつかのオープンソースToggleSwitches:
これに関して、適切なスライドアクション、完全な構成可能性を提供し、固定サイズである必要のないエントリを投稿しました(Webでそのようなソリューションを提供するものが見つからなかったため、イライラしました)。
ここにあります: http://itsallaboutthexaml.blogspot.com/2012/01/variables-in-animation.html
この質問への回答が遅れていることを知っておいてください。しかし、それが将来誰にも役立つことを願っています。
さて、私はこれと同じタスクを達成するために着手しましたが、例は実動コードに少し欠けていました。たとえば、On/Offやローカライズされたバージョンのテキストなどのコントロールにテキストを入力すると、コントロールをレンダリングした後にアニメーションまたはテンプレートトリガーを変更できないため、コントロールのサイズを定義する必要があります。これにより、ローカライズされたテキストでは機能しない万能ソリューションが得られます。
私の解決策は、コントロールのLoadedイベントとFrameworkElementFactoryクラスを使用して、コントロールのテンプレートを動的に作成することでした。私はそれははるかに複雑だったが、達成することができたと言わざるを得ない。コードビハインドに記述されているとおりにテンプレートを作成し、オン/オフテキストの依存関係プロパティを設定し、テキストメトリックを使用してコントロールの幅、高さ、およびアニメーション値を決定します。
現在、Avanquestに属しているため、ソリューションを投稿できないことを申し訳ありません。 :(
SystemSuiteおよびFix-It 12で探してください。
ArconautのNiceプロトタイプが好きで、境界線を丸くするためのコードを追加しました。
Grid宣言から「Background」プロパティを削除し、Grid宣言と最初のTextBlock宣言の間に次の行を追加する必要があります。
<Border
x:Name="back"
CornerRadius="3,3,3,3"
BorderThickness="1"
BorderBrush="#FFC0CCD9"
>
<Rectangle Fill="#FFC0CCD9"/>
</Border>