WPF - עיצוב כפתורי רדיו כמו checkbox
-
הדרך העצלנית היא משהו כזה:
<RadioButton> <RadioButton.Template> <ControlTemplate TargetType="RadioButton"> <CheckBox IsChecked="{TemplateBinding IsChecked}" /> </ControlTemplate> </RadioButton.Template> </RadioButton>
אפשר להחיל את זה בזריזות על כמה רדיואים ע"י ריסורס:
<RadioButton Template="{StaticResource template}" />
ובapp או בחלון בריסורס:
<Window.Resources> <ControlTemplate TargetType="RadioButton" x:Key="template" > <CheckBox IsChecked="{TemplateBinding IsChecked}" /> </ControlTemplate> </Window.Resources>
או סטייל שחל על כל הרדיואים (ללא key)
<Window.Resources> <Style TargetType="RadioButton"> <Style.Setters> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="RadioButton" > <CheckBox IsChecked="{TemplateBinding IsChecked}" /> </ControlTemplate> </Setter.Value> </Setter> </Style.Setters> </Style> </Window.Resources>
כבכל הדוגמאות האלה עשיתי בטמפלט פשוט checkbox שמאוגד לערך של הרדיו. אבל זה כמובן לא הדרך הנכונה (אלא שהיא קומפקטית לדוגמא בפורום...) הדרך הנכונה האי לצייר בדיוק כמו checkbox. הנה הדוגמא:
<ControlTemplate TargetType="RadioButton" > <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Border x:Name="checkBoxBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"> <Grid x:Name="markGrid"> <Path x:Name="optionMark" Data="F1 M 9.97498,1.22334L 4.6983,9.09834L 4.52164,9.09834L 0,5.19331L 1.27664,3.52165L 4.255,6.08833L 8.33331,1.52588e-005L 9.97498,1.22334 Z " Fill="{StaticResource OptionMark.Static.Glyph}" Margin="1" Opacity="0" Stretch="None"/> <Rectangle x:Name="indeterminateMark" Fill="{StaticResource OptionMark.Static.Glyph}" Margin="2" Opacity="0"/> </Grid> </Border> <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="HasContent" Value="true"> <Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/> <Setter Property="Padding" Value="4,-1,0,0"/> </Trigger> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.MouseOver.Background}"/> <Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.MouseOver.Border}"/> <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.MouseOver.Glyph}"/> <Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.MouseOver.Glyph}"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Disabled.Background}"/> <Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Disabled.Border}"/> <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.Disabled.Glyph}"/> <Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.Disabled.Glyph}"/> </Trigger> <Trigger Property="IsPressed" Value="true"> <Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Pressed.Background}"/> <Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Pressed.Border}"/> <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.Pressed.Glyph}"/> <Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.Pressed.Glyph}"/> </Trigger> <Trigger Property="IsChecked" Value="true"> <Setter Property="Opacity" TargetName="optionMark" Value="1"/> <Setter Property="Opacity" TargetName="indeterminateMark" Value="0"/> </Trigger> <Trigger Property="IsChecked" Value="{x:Null}"> <Setter Property="Opacity" TargetName="optionMark" Value="0"/> <Setter Property="Opacity" TargetName="indeterminateMark" Value="1"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate>
בגלל שהקוד הזה בנוי להשתמש מריסורסים אז יש להעתיק גם אותם לריסורס (או להחליף את ערכי הבינדינג לערכים מוחלטים):
<Style x:Key="FocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <SolidColorBrush x:Key="OptionMark.Static.Background" Color="#FFFFFFFF"/> <SolidColorBrush x:Key="OptionMark.Static.Border" Color="#FF707070"/> <Style x:Key="OptionMarkFocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Rectangle Margin="14,0,0,0" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <SolidColorBrush x:Key="OptionMark.MouseOver.Background" Color="#FFF3F9FF"/> <SolidColorBrush x:Key="OptionMark.MouseOver.Border" Color="#FF5593FF"/> <SolidColorBrush x:Key="OptionMark.MouseOver.Glyph" Color="#FF212121"/> <SolidColorBrush x:Key="OptionMark.Disabled.Background" Color="#FFE6E6E6"/> <SolidColorBrush x:Key="OptionMark.Disabled.Border" Color="#FFBCBCBC"/> <SolidColorBrush x:Key="OptionMark.Disabled.Glyph" Color="#FF707070"/> <SolidColorBrush x:Key="OptionMark.Pressed.Background" Color="#FFD9ECFF"/> <SolidColorBrush x:Key="OptionMark.Pressed.Border" Color="#FF3C77DD"/> <SolidColorBrush x:Key="OptionMark.Pressed.Glyph" Color="#FF212121"/> <SolidColorBrush x:Key="OptionMark.Static.Glyph" Color="#FF212121"/>
מנין ידעתי לצייר בדיוק כמו checkbox? פשוט העתקתי. מאיפה? ע"י שימוש בחלון Document Outline. ראשית אני יוצר checkbox בחלון, שנית אני הולך לחלון Document Outline ולוחץ קליק ימני על הchackbox ובת התפריט Edit Template אני בוחר בEdit a Copy (אתה נשאל האם אתה רוצה שהטמפלט יהיה באפליקציה - נגיש מכל החלונות, או בחלון הנוכחי. במקרה זה השאלה לא רלוונטית כי הקוד יימחק עוד כמה דקות כי הוא רק לצרכי העתקה). אח"כ בקוד שנוצר כתוב בדיוק איך יוצרי WPF ציירו את הCheckBox .
בשולי העניין, הצורך הזה לא נכון בעיני מבחינת חויית משתמש - זה חרגיה מנורמה וזה עלול לבלבל.
פורסם במקור בפורום CODE613 ב07/04/2017 10:34 (+03:00)