Featured image of post WPF控件库 BaseWPFControl

WPF控件库 BaseWPFControl

从底层开始实现的WPF自定义控件库,包含基础控件和自定义控件

简介

BaseWPFControl 是一个 dll,基于 .net 8.0WPF 框架实现,用于提供控件样式(包含基础控件和额外控件)。

基础控件

Button

重写了基础控件 Button 的样式。

  1. 新增 BaseWPFControl:ButtonProperty.Icon 附加属性用于提供按钮图标
  2. 提供圆角
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<Button Content="纯文字按钮" Margin="10" />

<Button Content="图标" Margin="10" 
        BaseWPFControl:ButtonProperty.Icon="{StaticResource HomePage}" />

<Button Content="圆形按钮" Margin="10" 
        Style="{StaticResource CircleButtonStyle}" />

<Button Content="带图标的圆形按钮" Margin="10" 
        Style="{StaticResource CircleButtonStyle}" 
        BaseWPFControl:ButtonProperty.Icon="{StaticResource HomePage}" />

<Button Content="跑道形按钮" Margin="10" 
        Style="{StaticResource RoundButtonStyle}" />

<Button Content="图标" Margin="10" 
        Style="{StaticResource RoundButtonStyle}" 
        BaseWPFControl:ButtonProperty.Icon="{StaticResource HomePage}" />

针对不启用和不可点击的按钮,做出了区分,分别对应 IsEnabledIsHitTestVisible 属性。

1
2
<Button Content="不启用" IsEnabled="False" Margin="10" />
<Button Content="不可点击" IsHitTestVisible="False" Margin="10" />

之所以这样去做目的是为了 GPIO 的控制,GPI 不可点击,GPO 可点击。

提供了两种相似的样式 BooleanStateButtonStyleBooleanToggleButtonStyle。前者对应于 GPI,不可点击,仅用于展示 GPI 状态,后者对应于 GPO,既可以展示 GPO 状态,又可以通过点击切换状态。

1
2
3
4
<Button Style="{StaticResource BooleanStateButtonStyle}" Margin="10" 
        Tag="{Binding State}" />
<Button Style="{StaticResource BooleanToggleButtonStyle}" Margin="10"
        Tag="{Binding State}" Command="{Binding ChangeStateCommand}" />

ToggleButton

基于 ToggleButton 重写样式,该控件的本意是用于 GPIO 的控制

1
2
3
<ToggleButton IsChecked="{Binding State}" Margin="10" />

<ToggleButton IsChecked="{Binding State}" Margin="10" IsEnabled="False" />

最终方案如下:

  • GPI 使用 ButtonBooleanStateButtonStyle 样式
  • GPO 使用 ToggleButton 的默认样式。

RadioButton

重写 RadioButton 的样式,主要优化如下:

  1. 勾选后样式变化
  2. 勾选框尺寸跟随字体尺寸变化
1
2
3
4
5
<RadioButton Content="未勾选" />
<RadioButton Content="勾选" IsChecked="True" />
<RadioButton Content="未勾选未启用" IsEnabled="False" IsChecked="False" />
<RadioButton Content="勾选未启用" IsEnabled="False" IsChecked="True"  />
<RadioButton Content="大字体" FontSize="30" />

CheckBox

重写 CheckBox 的样式,主要优化如下:

  1. 勾选后样式变化
  2. 勾选框圆角
  3. 勾选框尺寸跟随字体尺寸变化
1
2
3
4
5
<CheckBox Content="未勾选" />
<CheckBox Content="勾选" IsChecked="True" />
<CheckBox Content="未勾选未启用" IsEnabled="False" IsChecked="False" />
<CheckBox Content="勾选未启用" IsEnabled="False" IsChecked="True" />
<CheckBox Content="大字体" FontSize="30" />

ComboBox

重写 ComboBox 样式,主要优化如下:

  1. 圆角属性
  2. 提供 ComboBox 绑定枚举值的扩展语法 EnumBindingSource
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

<!--示例1:ComboBox绑定枚举值-->
<ComboBox Margin="10" Width="120"
          ItemsSource="{BaseWPFControl:EnumBindingSource 
                                        EnumType=BaseTest:EnumDayOfWeek}"
          SelectedItem="{Binding SelectedEnumDayOfWeek}" >
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding 
                       Converter={StaticResource EnumToDescriptionConverter}, 
                       Mode=OneWay}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

<!--示例2:不启用ComboBox-->
<ComboBox Margin="10" Width="120" IsEnabled="False" >
    <ComboBoxItem Content="1" IsSelected="True" />
</ComboBox>

<!--示例3:ComboBox绑定字典-->
<!--note:需要设置 DisplayMemberPath 和 SelectedValuePath,-->
<!--note:并只能使用 SelectedValue 进行访问-->
<ComboBox Margin="10" Width="120" ItemsSource="{Binding DictionaryDayOfWeek}"
          DisplayMemberPath="Value" SelectedValuePath="Key"
          SelectedValue="{Binding SelectedDictionaryDayOfWeek}" />

<!--示例4:ComboBox绑定列表-->
<!--note:使用 SelectedItem 或者 SelectedValue 都可以获得正确结果-->
<!--note: 前提是绑定的值在列表中,也可以通过 SelectedIndex 进行访问-->
<ComboBox Margin="10" Width="120" ItemsSource="{Binding ListDayOfWeek}"
          SelectedItem="{Binding SelectedListDayOfWeek}" />

TextBlock

重写 TextBlock 的样式,主要优化如下:

  1. 中英文使用不同的字体显示,中文使用微软雅黑,英文使用Consolas
1
2
<TextBlock Text="显示中文" Margin="10" />
<TextBlock Text="Show English" Margin="10" />

MemoryBlock

该控件为自定义控件,主要实现以下功能:

  1. 获取当前软件已使用内存,以 MB 为单位
  2. 可以通过控件的 Interval 属性设置更新频率,单位为 ms,默认为 1000 ms
  3. 可以通过控件的 Header 属性设置前缀文字
  4. 可以通过控件的 UsedMemory 只读属性获取内存
1
<BaseWPFControl:MemoryBlock Margin="10" />

LogBlock

该控件为自定义控件,配合 BaseLogManager 一起使用,主要实现以下功能:

  1. 显示日志
  2. 提供日志详情页
1
2
3
4
<BaseWPFControl:LogBlock x:Name="LogBlock_Test" />

<ContentControl Height="400" Margin="10"
                Content="{Binding ElementName=LogBlock_Test, Path=LogView}" />

TextBox

重写 TextBox 的样式,主要实现以下功能:

  1. 可以通过 TextBoxProperty.Prefix 属性设置前缀文字
  2. 可以通过 TextBoxProperty.WaterMask 属性设置水印文字
  3. 可以通过 TextBoxProperty.Suffix 属性设置后缀文字
  4. 输入时边框高亮显示
  5. 大文本输入框可以通过滚动条上下滚动
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<TextBox Width="200"  Margin="10" 
         BaseWPFControl:TextBoxProperty.Prefix="www." 
         BaseWPFControl:TextBoxProperty.Suffix=".com"
         BaseWPFControl:TextBoxProperty.WaterMask="输入网址" />
<TextBox Width="160" Margin="10" Text="默认文本框" />
<TextBox Width="100" Margin="10" 
         BaseWPFControl:TextBoxProperty.WaterMask="绑定Decimal类型"
         Text="{Binding DecimalNumber, StringFormat=0.#}" />

<TextBox Style="{StaticResource BigTextBox}" 
         Width="400" Height="100" Margin="10" Text="{Binding Poetry1}" />

NumericBox

NumericBox 为自定义控件,主要实现以下功能:

  1. 更方便的绑定数字,并提供限制
  2. 可以通过 Value 属性获取/设置值
  3. 可以通过 TextFormat 属性设置文本格式
  4. 可以通过 MinValue 属性设置最小值
  5. 可以通过 MaxValue 属性设置最大值
  6. 可以通过 Interval 属性设置点击增减按钮时的变化量
  7. 可以通过 ValueChanged 事件获取值改变事件
1
2
3
4
5
<BaseWPFControl:NumericBox Value="{Binding DecimalNumber}" TextFormat="0.#" 
                           MinValue = "0" MaxValue = "100" Interval = "1"
                           ValueChanged="NumericBox_ValueChanged" />
<BaseWPFControl:NumericBox Value="{Binding DecimalNumber}" TextFormat="0.#" 
                           IsEnabled="False" />

PasswordBox

重写 PasswordBox 样式,主要实现以下功能:

  1. 可以通过 PasswordBoxProperty.CanShowPassword 属性设置是否显示密码的功能
1
2
3
<PasswordBox Width="200" Margin="10" Password="123456" />
<PasswordBox Width="200" Margin="10" Password="123456" 
             BaseWPFControl:PasswordBoxProperty.CanShowPassword="False" />

DatePicker & DateTimePicker

DatePickerDateTimePicker 都是自定义控件,主要实现以下功能:

  1. 选择时间和日期,这两个控件的区别在于一个前者只有日期,后者包含时间
  2. 可以通过 SelectedDateTime 获取选中的日期时间
  3. 可以通过 SelectedDateTimeFormat 设置日期时间的格式
  4. 可以通过 SelectedDateTimeChanged 获取时间改变的事件
1
2
<BaseWPFControl:DatePicker Margin="10" />
<BaseWPFControl:DateTimePicker Margin="10" />

SelectFileBlock & SelectFolderBlock

SelectFileBlockSelectFolderBlock 都是自定义控件,主要实现以下功能:

  1. 点击按钮通过对话框选择文件或者文件夹
  2. 可以通过 SelectedPath 属性获取/设置路径
  3. 可以通过 SelectedPathChanged 获取选中路径改变的事件
  4. SelectFileBlock 可以通过 ExtensionFilter 属性设置文件过滤
  5. 鼠标移动到文字上方出现 ToolTip 显示路径的全文
  6. 鼠标双击文字直接跳转到路径所在的文件夹

Image

提供一些内置的 SVG,可以直接通过 Source 绑定 StaticResource 值进行设置

1
<Image Source="{StaticResource DirectoryConfig}" Height="50" Margin="10" />

ProgressBar & Loading

  1. 重写 ProgressBar 样式,提供圆角
  2. 可以通过 ProgressBarProperty.ShowValue 属性设置进度条显示当前值
  3. 提供扩展函数 SetAnimateValue 设置进度条的值,通过该函数设置可以显示动画
  4. 提供自定义控件圆形进度条 Loading,仅用于等待功能
1
2
3
4
<ProgressBar Height="40" Width="400" d:Value="20"/>
<ProgressBar Height="40" Width="400" IsIndeterminate="True"/>
<BaseWPFControl:Loading Diameter="150" StrokeThickness="30" 
                        Content="加载中,请等待..." />

Clock & Calendar

  1. 重写 Calender 样式
  2. 提供 自定义控件 Clock,用于选择时间
1
2
3
<Calendar x:Name = "Calendar" />

<BaseWPFControl:Clock Height="{Binding ActualHeight, ElementName=Calender}"/>

TabControl

重写 TabControl 的样式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<TabControl TabStripPlacement="Left">
    <TabItem Header="水调歌头" >
        <TextBlock Text="{Binding Poetry1}" FontSize="14" />
    </TabItem>
    <TabItem Header="如梦令" >
        <TextBlock Text="{Binding Poetry2}" FontSize="14" />
    </TabItem>
    <TabItem Header="破阵子" >
        <TextBlock Text="{Binding Poetry3}" FontSize="14" />
    </TabItem>
    <TabItem Header="未启用" IsEnabled="False" />
</TabControl>

复杂控件

ConfigControl

提供自定义控件 ConfigControl,用于方便的实现配置界面

1
2
3
4
5
6
7
<BaseWPFControl:ConfigControl ConfigName="日期时间">
    <BaseWPFControl:DateTimePicker />
</BaseWPFControl:ConfigControl>

<BaseWPFControl:ConfigControl ConfigName="选择文件">
    <BaseWPFControl:SelectFileBlock Width="280" />
</BaseWPFControl:ConfigControl>

LisBox

重写 ListBox 的样式,可以绑定 Enum/List/Dictionary

ListView

  1. 重写 ListView 的样式

DataGrid

重写 DataGrid 的样式,这里包含两种样式,一种是选择单元格,另一种是鼠标经过选中整行

选中单元格 无法选中,鼠标经过选中整行

使用 Hugo 构建
主题 StackJimmy 设计