c# WPF中CheckBox样式的使用总结

背景

  很多时候我们使用WPF开发界面的时候经常会用到各种空间,很多时候我们需要去自定义控件的样式来替换默认的样式,今天通过两个方法来替换WPF中的CheckBox样式,透过这两个例子我们可以掌握基本的WPF样式的开发如何定义ControlTemplate以及使用附加属性来为我们的控件增加新的样式。

常规使用

  我们在使用CheckBox的时候,原始的样式有时不能满足我们的需求,这是我们就需要更改其模板,比如我们常用的一种,在播放器中“播放”、“暂停”按钮,其实这也是一种CheckBox,只不过我们只是修改了其相关的模板罢了,下面贴出相关代码:

<CheckBox.Style>
  <Style TargetType="{x:Type CheckBox}">
    <Setter Property="Focusable" Value="False" />
    <Setter Property="IsTabStop" Value="False" />
    <!--把OverridesDefaultStyle设置为True,表示这个控件不使用当前Themes的任何属性。-->
    <Setter Property="OverridesDefaultStyle" Value="True" />
      <Style.Triggers>
        <Trigger Property="IsChecked" Value="True">
       <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
              <Grid Background="Transparent">
                   <Image Source="/EarthSimulation;component/Images/按钮-播放.png"/>
              </Grid>
            </ControlTemplate>
         </Setter.Value>
      </Setter>
      </Trigger>
      <Trigger Property="IsChecked" Value="False">
       <Setter Property="Template">
         <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <Grid Background="Transparent">
                        <Image Source="/EarthSimulation;component/Images/按钮-暂停.png"/>
                 </Grid>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
        </Trigger>
      </Style.Triggers>
    </Style>
  </CheckBox.Style>
</CheckBox>  

进阶用法

  上面的使用较为简单,下面我们通过一个更加复杂一些的例子来增加对自定义控件模板的理解,我们先来看看我们定义的样式。

<Style x:Key="CheckBoxStyle" TargetType="{x:Type CheckBox}">
               <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
               <Setter Property="Background" Value="Transparent"/>
               <Setter Property="BorderBrush" Value="Transparent"/>
               <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
               <Setter Property="Template">
                   <Setter.Value>
                       <ControlTemplate TargetType="{x:Type CheckBox}">
                           <Border x:Name="templateRoot" Background="{TemplateBinding Background}" >
                               <Grid SnapsToDevicePixels="True">
                                   <Grid.Resources>
                                       <PathGeometry x:Key="geometryCheck" Figures="M540.5696 102.4c-225.83296 0-409.6 183.74656-409.6 409.6s183.76704 409.6 409.6 409.6c225.87392 0 409.6-183.74656 409.6-409.6S766.44352 102.4 540.5696 102.4zM721.16224 468.48l-175.37024 175.39072c-12.20608 12.1856-28.20096 18.28864-44.19584 18.28864-15.95392 0-31.96928-6.10304-44.15488-18.28864l-97.44384-97.44384c-24.39168-24.39168-24.39168-63.93856 0-88.33024 24.39168-24.41216 63.91808-24.41216 88.35072 0l53.248 53.248 131.23584-131.21536c24.35072-24.3712 63.95904-24.3712 88.33024 0C745.55392 404.52096 745.55392 444.08832 721.16224 468.48z"/>
                                   </Grid.Resources>
                                   <Grid.ColumnDefinitions>
                                       <ColumnDefinition Width="20"/>
                                       <ColumnDefinition Width="*"/>
                                       <ColumnDefinition Width="30"/>
                                   </Grid.ColumnDefinitions>
 
                                   <Border>
                                       <Path Width="18" Height="18" Stretch="Uniform"
                                             Data="{Binding (local_ctrl:GeometryAP.IconGeometry), RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type CheckBox}}}"
                                             Fill="{Binding (local_ctrl:GeometryAP.IconFill), RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type CheckBox}}}"/>
                                   </Border>
                                   <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False"
                                                 Margin="{TemplateBinding Padding}"
                                                 RecognizesAccessKey="True"
                                                 SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                                 HorizontalAlignment="Left"
                                                 VerticalAlignment="Center"/>
 
                                   <Border x:Name="checkBoxBorder"
                                       Grid.Column="2"
                                       Margin="1"
                                       BorderBrush="Transparent"
                                       BorderThickness="1"
                                       Background="Transparent"
                                       HorizontalAlignment="Left"
                                       VerticalAlignment="Center">
 
                                       <Grid x:Name="markGrid">
                                           <Path x:Name="optionMark" Width="20" Height="20"
                                                 Stretch="Uniform"
                                                 Data="{StaticResource geometryCheck}"
                                                 Fill="LightSeaGreen" Margin="1" Opacity="0"/>
                                       </Grid>
                                   </Border>
                               </Grid>
                           </Border>
                           <ControlTemplate.Triggers>
                               <Trigger Property="HasContent" Value="true">
                                   <Setter Property="Padding" Value="4,-1,0,0"/>
                               </Trigger>
                               <Trigger Property="IsMouseOver" Value="true">
                                   <Setter Property="Cursor" Value="Hand"/>
                                   <Setter Property="Background" Value="#22222222"/>
                               </Trigger>
                               <Trigger Property="IsEnabled" Value="false">
                                   <Setter Property="Opacity" Value=".3"/>
                               </Trigger>
                               <Trigger Property="IsPressed" Value="true">
                                   <Setter Property="Cursor" Value="Hand"/>
                                   <Setter Property="Background" Value="#22333333"/>
                               </Trigger>
                               <Trigger Property="IsChecked" Value="true">
                                   <Setter Property="Opacity" TargetName="optionMark" Value="1"/>
                               </Trigger>                               
                           </ControlTemplate.Triggers>
                       </ControlTemplate>
                   </Setter.Value>
               </Setter>
           </Style>

  后面我们再来看看,我们使用CheckBox的地方。

<CheckBox Grid.Row="1" Grid.Column="1"
                                      IsChecked="{Binding VM.IsHorizontal,ElementName=_this}" Content="Horizontal"
                                      Style="{StaticResource CheckBoxStyle}"
                                      local_ctrl:GeometryAP.IconGeometry="{StaticResource geometryDirection}"
                                      local_ctrl:GeometryAP.IconFill="LightSeaGreen"/>

  这个地方我们为CheckBox增加了两个附加属性IconGeometry、IconFill这样我们就能够将这两个附加属性绑定到CheckBox样式中的Path里面的Data和Fill依赖项属性上面,通过上面的过程我们就能够定义各种各样的CheckBox样式了,下面我们看看我们定义的这两个附加属性具体的代码。

public class GeometryAP : DependencyObject
{
    public static PathGeometry GetIconGeometry(DependencyObject obj)
    {
        return (PathGeometry)obj.GetValue(IconGeometryProperty);
    }
    public static void SetIconGeometry(DependencyObject obj, PathGeometry value)
    {
        obj.SetValue(IconGeometryProperty, value);
    }
 
    public static Brush GetIconFill(DependencyObject obj)
    {
        return (Brush)obj.GetValue(IconFillProperty);
    }
    public static void SetIconFill(DependencyObject obj, Brush brush)
    {
        obj.SetValue(IconFillProperty, brush);
    }
 
    public static readonly DependencyProperty IconGeometryProperty = DependencyProperty.RegisterAttached("IconGeometry", typeof(PathGeometry), typeof(GeometryAP));
    public static readonly DependencyProperty IconFillProperty = DependencyProperty.RegisterAttached("IconFill", typeof(Brush), typeof(GeometryAP), new PropertyMetadata(Brushes.Transparent));
}

  样式欣赏

以上就是c# WPF中CheckBox样式的使用总结的详细内容,更多关于c# WPF中CheckBox样式的资料请关注我们其它相关文章!

(0)

相关推荐

  • C# WPF 建立无边框(标题栏)的登录窗口的示例

    前言:笔者最近用c#写WPF做了一个项目,此前未曾做过完整的WPF项目,算是一边学一边用,网上搜了不少资料,效率当然是不敢恭维的,有时会在一些很简单的问题上纠结很长时间,血与泪的教训可不少. 不过,正如电视剧某榜里的一句话:既然我活了下来,就不会白白活着!笔者怎么也算挣扎过了,有些经验与教训可以分享,趁着记忆深刻总结写下来.希望后来者少走弯路,提高工作效率.如果有写得不好的地方,希望读者能够指正,一起进步! --------------------------------- 今天先从登录窗口说起

  • C# WPF Image控件的绑定方法

    在我们平时的开发中会经常用到Image控件,通过设置Image控件的Source属性,我们可以加载图片,设置Image的source属性时可以使用相对路径也可以使用绝对路径,一般情况下建议使用绝对路径,类似于下面的形式Source="/Demo;Component/Images/Test.jpg"其中Demo表示工程的名称,后面表示具体哪个文件夹下面的哪个图片资源,在程序中,我们甚至可以为Image控件设置X:Name属性,在后台代码中动态去改变Image的Source,但我个人认为这

  • 浅谈c# WPF中的PreviewTextInput

    今天在使用TextBox的TextInput事件的时候,发现无论如何都不能触发该事件,然后百思不得其解,最后在MSDN上找到了答案:TextInput 事件可能已被标记为由复合控件的内部实现进行处理.例如,TextBox 就是这样一个控件:在其组合期间已将 TextInput 事件标记为已处理.之所以这么做是因为,控件需要将某些类型的输入(如箭头键)解释为对该控件具有特殊含义.如果将 PreviewTextInput 事件用于为文本输入附加处理程序,则会获得更好的效果.该技术可以应对控件组合将此

  • C# WPF 自定义按钮的方法

    本文介绍WPF一种自定义按钮的方法. 实现效果 使用图片做按钮背景: 自定义鼠标进入时效果: 自定义按压效果: 自定义禁用效果 实现效果如下图所示: 实现步骤 创建CustomButton.cs,继承自Button: 创建一个资源文件ButtonStyles.xaml: 在资源文件中设计按钮的Style: 在CustomButton.cs中添加Style中需要的依赖属性: 在程序中添加资源并引用(为了方便在不同的程序中引用自定义按钮,自定义按钮放在独立的类库中,应用程序中进行资源合并即可). 示

  • c# WPF中自定义加载时实现带动画效果的Form和FormItem

    背景 今天我们来谈一下我们自定义的一组WPF控件Form和FormItem,然后看一下如何自定义一组完整地组合WPF控件,在我们很多界面显示的时候我们需要同时显示文本.图片并且我们需要将这些按照特定的顺序整齐的排列在一起,这样的操作当然通过定义Grid和StackPanel然后组合在一起当然也是可以的,我们的这一组控件就是将这个过程组合到一个Form和FormItem中间去,从而达到这样的效果,我们首先来看看这组控件实现的效果. 一 动画效果 看了这个效果之后我们来看看怎么来使用Form和For

  • c# WPF中System.Windows.Interactivity的使用

    背景 在我们进行WPF开发应用程序的时候不可避免的要使用到事件,很多时候没有严格按照MVVM模式进行开发的时候习惯直接在xaml中定义事件,然后再在对应的.cs文件中直接写事件的处理过程,这种处理方式写起来非常简单而且不用过多地处理考虑代码之间是否符合规范,但是我们在写代码的时候如果完全按照WPF规范的MVVM模式进行开发的时候就应该将相应的事件处理写在ViewModel层,这样整个代码才更加符合规范而且层次也更加清楚,更加符合MVVM规范. 常规用法 1 引入命名空间 通过在代码中引入Syst

  • C#中WPF依赖属性的正确学习方法

    前言 我在学习WPF的早期,对依赖属性理解一直都非常的不到位,其恶果就是,我每次在写依赖属性的时候,需要翻过去的代码来复制黏贴. 相信很多朋友有着和我相同的经历,所以这篇文章希望能帮助到那些刚刚开始学依赖属性的朋友. 那些[讨厌]的依赖属性的讲解文章 初学者肯定会面临一件事,就是百度,谷歌,或者MSDN来查看依赖属性的定义和使用,而这些文章虽然都写的很好,但,那是相对于已经学会使用依赖属性的朋友而言. 而对于初学者而言,说是误导都不过分. 比如,官网的这篇文章https://docs.micro

  • c# WPF中通过双击编辑DataGrid中Cell的示例(附源码)

    背景 在很多的时候我们需要编辑DataGrid中每一个Cell,编辑后保存数据,原生的WPF中的DataGrid并没有提供这样的功能,今天通过一个具体的例子来实现这一个功能,在这个例子中DataGrid中的数据类型可能是多种多样的,有枚举.浮点类型.布尔类型.DateTime类型,每一种不同的类型需要双击以后呈现不同的效果,本文通过使用Xceed.Wpf.DataGrid这个动态控件库来实现这个功能,当前使用的Dll版本是2.5.0.0,不同的版本可能实现上面有差别,这个在使用的时候需要特别注意

  • c# WPF实现Windows资源管理器(附源码)

      今天我来写一篇关于利用WPF来实现Windows的资源管理器功能,当然只是局部实现这个功能,因为在很多时候我们需要来实现对本机资源的管理,当然我们可以使用OpenFileDialog dialog = new OpenFileDialog()这个Microsoft.Win32命名空间下的这个类来实现一些资源查找和导入的功能,但是在很多时候我们可能需要更多的功能,并且希望能够集成到我们自己的项目中,但是我们这个时候就不得不自己来写一套来集成到我们的软件中去了,因为OpenFileDialog这

  • c# WPF如何实现滚动显示的TextBlock

    在我们使用TextBlock进行数据显示时,经常会遇到这样一种情况就是TextBlock的文字内容太多,如果全部显示的话会占据大量的界面,这是我们就会只让其显示一部分,另外的一部分就让其随着时间的推移去滚动进行显示,但是WPF默认提供的TextBlock是不具备这种功能的,那么怎么去实现呢? 其实个人认为思路还是比较清楚的,就是自己定义一个UserControl,然后将WPF简单的元素进行组合,最终实现一个自定义控件,所以我们顺着这个思路就很容易去实现了,我们知道Canvas这个控件可以通过设置

  • c# WPF中如何自定义MarkupExtension

    在介绍这一篇文章之前,我们首先来回顾一下WPF中的一些基础的概念,首先当然是XAML了,XAML全称是Extensible Application Markup Language (可扩展应用程序标记语言),是专门用于WPF技术中的UI设计语言,通过使用XAML语言,我们能够快速设计软件界面,同时能够通过绑定这种机制能够很好地实现界面和实现逻辑之间的解耦,这个就是MVVM模式的核心了,那么今天我们介绍的MarkupExtension和XAML之间又有哪些的关系呢? Markup Extensio

随机推荐