Tại sao lại RadioButton?
Vì RadioButton đã hỗ trợ sẵn thuộc tính GroupName, bạn có thể gom nhóm các RadioButton. để có được các template mặc định cho các trạng thái focus/unfocus.
Một nút thông thường trong Hamburger Menu của Windows 10 bao gồm 1 icon bên trái và nội dung bên phải. Có thể dễ dàng sửa lại template của RadioButton cho hợp bằng Blend.
Dùng Blend để xem template mặc định của RadioButton
Mở trang đang chứa RadioButton cần sửa bằng Blend như sau:
Blend sẽ có giao diện thế này (mỗi máy sẽ có cách hiển thị khác nhau).
Chú ý vào cửa sổ Objects and Timeline, sổ cây objects ra để tìm một RadioButton mà bạn muốn chỉnh sửa lại template.
Chỉnh sửa tên Style cho phù hợp, trong đó chọn Application thì Style này sẽ nằm torng Resource của cả App (trong App.xaml), ở đây mình chọn This Document để style này chỉ nằm trong file xaml hiện tại.
Blend sẽ sinh ra cho bạn 1 style dài thật dài, đây chính là style mặc định do Windows 10 định nghĩa cho mọi RadioButton.
Đây gọi là 1 trạng thái (State), và bên trong là 1 storyboard với các Target khác nhau. Như vậy, khi nhấn chuột, lần lượt các thuộc tính Stroke hay Fill của OuterEllipse, CheckOuterEllipse, CheckGlyph sẽ thay đổi thành giá trị mới.
Các trạng thái khác cũng được hiểu tương tự. Còn này là sắp xếp layout:
Chỗ này dễ hiểu nè, 1 Grid 2 column, column bên trái chứa 3 cái ellipse với tên đã thấy xuất hiện trên các state, thuộc tính bla bla bla. Túm lại nó là cái cục tròn tròn nằm trước cái RadioButton , 1 ContentPresenter nằm ở cột phải để hiển thị nội dung (ta không thay đổi phần này).
Sửa template
Vậy ta cần sửa những gì, đầu tiên là ta muốn bên cột trái không phải là 1 ellipse nữa mà là 1 icon.
Hô biến, xóa hết cái Grid chứa 3 cái Ellipse. Nếu đã xóa mấy cái ellipse rồi thì TargetName ở trên cũng vô nghĩa, xóa nốt các Animation nào xuất hiện tên các ellipse này. Nhớ chừa thẻ Storyboard ra nhé, vì vẫn cần dùng tới.
Khai báo thêm 3 Brush là 3 màu sẽ thay đổi cho 3 trạng thái Pressed, Checked, Hover. Các này tùy thích mỗi người mà chọn
[codesyntax lang=”xml” title=”RadioButton Brush”]
<SolidColorBrush x:Key="MenuButtonPressedBackgroundBrush" Color="White" Opacity=0.3" /> <SolidColorBrush x:Key="MenuButtonCheckedBackgroundBrush" Color="White" Opacity=0.2" /> <SolidColorBrush x:Key="MenuButtonHoverBackgroundBrush" Color="White" Opacity=0.1" />
[/codesyntax]
Dùng các Brush này vào các Animation, cuối cùng ta được bộ resource template mới cho RadioButton
[codesyntax lang=”xml” title=”RadioButton template”]
<SolidColorBrush x:Key="MenuButtonPressedBackgroundBrush" Color="White" Opacity="0.3" /> <SolidColorBrush x:Key="MenuButtonCheckedBackgroundBrush" Color="White" Opacity="0.2" /> <SolidColorBrush x:Key="MenuButtonHoverBackgroundBrush" Color="White" Opacity="0.1" /> <Style x:Key="MenuRadioButtonStyle" TargetType="RadioButton"> <Setter Property="Background" Value="Transparent"/> <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/> <Setter Property="Padding" Value="8,6,0,0"/> <Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="HorizontalContentAlignment" Value="Left"/> <Setter Property="VerticalContentAlignment" Value="Top"/> <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/> <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/> <Setter Property="MinWidth" Value="30"/> <Setter Property="UseSystemFocusVisuals" Value="True"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="RadioButton"> <Grid x:Name="BackgroundGrid" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"/> <VisualState x:Name="PointerOver"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundGrid"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MenuButtonHoverBackgroundBrush}"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundGrid"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MenuButtonPressedBackgroundBrush}"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Disabled" /> </VisualStateGroup> <VisualStateGroup x:Name="CheckStates"> <VisualState x:Name="Checked"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundGrid"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MenuButtonCheckedBackgroundBrush}"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Unchecked"/> <VisualState x:Name="Indeterminate"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Grid.ColumnDefinitions> <ColumnDefinition Width="48"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <FontIcon Glyph="{TemplateBinding Tag}" Margin="4,4,4,4" FontSize="24" VerticalAlignment="Center"/> <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" TextWrapping="Wrap" VerticalAlignment="Center"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
[/codesyntax]
Ta cần dùng một thuộc tính chỉ định icon cần dùng, và không muốn viết một control khác chỉ vì thêm 1 thuộc tính. Do đó mình dùng Tag cho việc này. RadioButton sau cùng sẽ như thế này:
[codesyntax lang=”xml” title=”RadioButton usage”]
<RadioButton x:Name="MenuBtn" Click="MenuBtn_Click" Tag="" Content="Menu" GroupName="Menu" Style="{StaticResource MenuRadioButtonStyle}" Width="240" Height="40" FontSize="20"/>
[/codesyntax]
Bảng mã của các icon và cách dùng FontIcon chi tiết nằm ở bài viết này
Code của phần này có thể xem ở đây
Vậy là xong 1 item trong hamburger menu. Hướng dẫn cách làm 1 Hamburger menu trong Windows 10 được trình bày ở bài viết này