Quellcode durchsuchen

1.新增NumpadControl数字小键盘,方便输入。
2.更新Readme文档

Jiangsheng vor 4 Wochen
Ursprung
Commit
467cc77330

+ 35 - 2
Readme.md

@@ -1,6 +1,6 @@
 # 基础UI库(SKMC.UI)
 
-统一资源,统一样式,统一字体,控件自定义。
+统一资源,统一样式,统一字体,自定义控件自定义用户控件
 
 ## 基础说明
 主要分类:Assets资源文件、Converters基础转换器、CustomControls自定义控件、Styles控件样式、Themes主题、ValidationRules校验规则资源。
@@ -343,6 +343,7 @@ xmlns:c="clr-namespace:SKMC.UI.CustomControls;assembly=SKMC.UI"
 	Background="{StaticResource Brush.DebugLog}"
 	IconSize="{StaticResource FontSize.Callout}"/>
 ```
+> Button.WithIcon样式:设置*Icon*属性按钮将会显示图标;不设置默认不显示。设置*IconSize*将根据设置值调整Icon图标大小,宽度长度相同。
 - Button.Debug
 ```
 <Button Command="{Binding ExceptionTestCommand}" Style="{StaticResource Button.Debug}"
@@ -623,6 +624,9 @@ xmlns:c="clr-namespace:SKMC.UI.CustomControls;assembly=SKMC.UI"
 	Grid.ColumnSpan="3"
 	Margin="0 1 5 0"/>
 ```
+> Unit属性:显示文本框输入内容的单位,不设置不显示。UnitSize属性:设置Unit单位显示大小。Icon属性:显示文本框的图标,不设置不显示。NumpadActivity属性:True激活数字输入小键盘,False不激活小键盘,默认值False。
+> SKTextBox类:内部可根据具体需求增加依赖属性,即使创建不使用也无太大影响。
+
 - TextBox.SimpleWatermark
 ```
 <TextBox x:Name="productCodetbx" Width="250" Height="30" FontSize="15"
@@ -630,7 +634,7 @@ xmlns:c="clr-namespace:SKMC.UI.CustomControls;assembly=SKMC.UI"
          Style="{StaticResource TextBox.SimpleWatermark}"
          Tag="请输入产品码查询">
 ```
-####
+#### ToggleButton
 - ToggleButton.Base
 - ToggleButton.Primary
 - ToggleButton.SimpleLamp
@@ -662,6 +666,35 @@ xmlns:c="clr-namespace:SKMC.UI.CustomControls;assembly=SKMC.UI"
 	Margin="10"
 	ToolTip="切换主题"/>
 ```
+### 用户控件
+#### NumpadControl
+- NumpadControl.xaml
+```
+<DataGrid
+	x:Name="SpeedGrid"
+	Grid.Row="1"
+	Margin="10,10,10,10"
+	Style="{StaticResource DataGrid.Primary}"
+	ItemsSource="{Binding RecipeSpeeds, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
+	<DataGrid.Columns>
+		<DataGridTemplateColumn Header="最大速度(mm/s)" Width="*">
+			<DataGridTemplateColumn.CellTemplate>
+				<DataTemplate>
+					<c:SKTextBox Text="{Binding VelInput, UpdateSourceTrigger=PropertyChanged}"
+								 Style="{StaticResource TextBox.Primary}"
+								 NumpadActivity="True"
+								 BorderThickness="0"
+								 Unit="mm/s"
+								 FontSize="{StaticResource FontSize.Body}"/>
+				</DataTemplate>
+			</DataGridTemplateColumn.CellTemplate>
+		</DataGridTemplateColumn>
+	</DataGrid.Columns>
+</DataGrid>
+```
+> NumpadControl数字键盘控件依附**SKTextBox**控件,且输入文本框属性*NumpadActivity*设置为True,在鼠标点击文本框时弹出数字小键盘。*NumpadActivity*设置为False,文本框为普通输入框不弹数字键盘。
+> NumpadControl数字键盘内文本框可根据**SKTextBox**同步显示单位,若**SKTextBox**设置了单位,则数字键盘内显示相同单位,反之则无。
+
 ## 安装说明
 
 1. 克隆或下载本项目

+ 0 - 3
SKMC.UI/Assets/Icons.xaml

@@ -1094,9 +1094,6 @@
         <PathGeometry Figures="M13.294,53.169c0.718,0,1.444-0.177,2.113-0.565l47.22-27.267c0.966-0.557,1.676-1.478,1.965-2.559   c0.285-1.085,0.14-2.241-0.425-3.207C55.479,4.529,36.19-0.634,21.155,8.045c-7.284,4.21-12.492,10.994-14.671,19.12   C4.31,35.295,5.428,43.78,9.625,51.056C10.413,52.418,11.833,53.169,13.294,53.169 M14.647,29.353   c1.589-5.943,5.41-10.912,10.734-13.99c3.615-2.084,7.572-3.083,11.477-3.083c6.62,0,13.091,2.848,17.54,8.048L15.163,42.976   C13.624,38.634,13.43,33.917,14.647,29.353" />
         <PathGeometry Figures="M103.785,25.345l47.221,27.267c0.652,0.371,1.379,0.565,2.113,0.565c0.363,0,0.734-0.049,1.098-0.144   c1.081-0.289,2.006-0.999,2.559-1.969c4.209-7.288,5.324-15.773,3.152-23.895c-2.179-8.122-7.387-14.919-14.666-19.116   c-15.047-8.683-34.345-3.516-43.02,11.527c-0.554,0.974-0.719,2.121-0.43,3.202C102.102,23.855,102.803,24.78,103.785,25.345    M141.027,15.362c9.739,5.629,13.833,17.362,10.21,27.613l-39.239-22.653C119.071,12.073,131.279,9.733,141.027,15.362" />
     </GeometryGroup>
-    <GeometryGroup x:Key="Icon.Jet" FillRule="EvenOdd">
-        <PathGeometry Figures="M30.38,0H10A10,10,0,0,0,0,10V24.39L11.34,6.05H22.07V28H26.5v6.56H22.07v5.92h8.31a10,10,0,0,0,10-10V10a10,10,0,0,0-10-10M10,40.45h3.82V34.53H.89A10,10,0,0,0,10,40.45m.35-20.77L5.4,27.86l0,.11h8.46V19.68c0-2.24.1-4.54.2-6.95h-.17c-1.2,2.41-2.23,4.61-3.5,7" />
-    </GeometryGroup>
     <GeometryGroup x:Key="Icon.Trapezoid">
         <LineGeometry StartPoint="-35,-15" EndPoint="-15,15" />
         <LineGeometry StartPoint="-15,15" EndPoint="15,15" />

+ 77 - 1
SKMC.UI/CustomControls/SKTextBox.cs

@@ -1,4 +1,5 @@
-using System;
+using SKMC.UI.UserControls;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -15,6 +16,12 @@ namespace SKMC.UI.CustomControls
         {
             DefaultStyleKeyProperty.OverrideMetadata(typeof(SKTextBox), new FrameworkPropertyMetadata(typeof(SKTextBox)));
         }
+        public SKTextBox()
+        {
+            this.PreviewMouseDown += SKTextBox_PreviewMouseDown;
+            //this.GotFocus += SKTextBox_GotFocus;
+        }
+
         public string Label
         {
             get { return (string)GetValue(LabelProperty); }
@@ -91,6 +98,20 @@ namespace SKMC.UI.CustomControls
             set { SetValue(IconSizeProperty, value); }
         }
 
+        /// <summary>
+        /// 数字键盘激活
+        /// </summary>
+        public bool NumpadActivity
+        {
+            get { return (bool)GetValue(NumpadActivityProperty); }
+            set { SetValue(NumpadActivityProperty, value); }
+        }
+
+        public static readonly DependencyProperty NumpadActivityProperty =
+            DependencyProperty.Register(nameof(NumpadActivity), typeof(bool), typeof(SKTextBox), new PropertyMetadata(false));
+
+
+
         public static readonly DependencyProperty IconProperty =
             DependencyProperty.Register("Icon", typeof(Geometry), typeof(SKTextBox), new PropertyMetadata(null));
 
@@ -121,5 +142,60 @@ namespace SKMC.UI.CustomControls
 
         public static readonly DependencyProperty IconSizeProperty =
             DependencyProperty.Register(nameof(IconSize), typeof(double), typeof(SKTextBox), new PropertyMetadata(10.0));
+
+        /// <summary>
+        /// 鼠标点击时激活键盘
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void SKTextBox_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+        {
+            if (!NumpadActivity) return;
+            if (sender is SKTextBox textBox)
+            {
+                // 打开数字键盘
+                OpenNumpad(textBox);
+
+                // 防止默认的焦点行为
+                e.Handled = true;
+            }
+        }
+        // 获取焦点时激活键盘(作为备选)
+        //private void SKTextBox_GotFocus(object sender, RoutedEventArgs e)
+        //{
+        //    if (sender is SKTextBox textBox)
+        //    {
+        //        OpenNumpad(textBox);
+        //    }
+        //}
+        // 打开数字键盘
+        private void OpenNumpad(SKTextBox textBox)
+        {
+            if (!NumpadActivity) return;
+            try
+            {
+                // 创建键盘窗口
+                NumpadControl numpadWindow = new NumpadControl(textBox);
+
+                // 设置窗口位置在父窗口中央
+                numpadWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
+
+                // 显示对话框
+                bool? result = numpadWindow.ShowDialog();
+
+                // 如果确认了输入,更新文本框
+                if (result == true && numpadWindow.IsConfirmed)
+                {
+                    textBox.Text = numpadWindow.InputResult;
+                    // 更新光标位置
+                    textBox.CaretIndex = textBox.Text.Length;
+                }
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show($"打开键盘失败:{ex.Message}", "错误",
+                              MessageBoxButton.OK, MessageBoxImage.Error);
+            }
+        }
     }
 }

+ 8 - 0
SKMC.UI/SKMC.UI.csproj

@@ -22,6 +22,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x64</PlatformTarget>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
@@ -73,6 +74,9 @@
       <DesignTimeSharedInput>True</DesignTimeSharedInput>
     </Compile>
     <Compile Include="Themes\ThemeManager.cs" />
+    <Compile Include="UserControls\NumpadControl.xaml.cs">
+      <DependentUpon>NumpadControl.xaml</DependentUpon>
+    </Compile>
     <Compile Include="ValidationRules\DateTimeRule.cs" />
     <Compile Include="ValidationRules\RangeValidationRule.cs" />
     <EmbeddedResource Include="Properties\Resources.resx">
@@ -86,6 +90,10 @@
   </ItemGroup>
   <ItemGroup />
   <ItemGroup>
+    <Page Include="UserControls\NumpadControl.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
     <Resource Include="Assets\Brushes.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 23 - 8
SKMC.UI/Styles/TextBlock.xaml

@@ -1,11 +1,26 @@
-<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
     <Style x:Key="TextBlock.Primary" TargetType="{x:Type TextBlock}">
-        <Setter Property="FontSize" Value="{DynamicResource FontSize.Callout}"/>
-        <Setter Property="FontFamily" Value="{DynamicResource FontFamily.Global}"/>
-        <Setter Property="Foreground" Value="{DynamicResource Brush.Text}"/>
-        <Setter Property="FontWeight" Value="Bold"/>
-        <Setter Property="HorizontalAlignment" Value="Center"/>
-        <Setter Property="VerticalAlignment" Value="Center"/>
+        <Setter Property="FontSize" Value="{DynamicResource FontSize.Callout}" />
+        <Setter Property="FontFamily" Value="{DynamicResource FontFamily.Global}" />
+        <Setter Property="Foreground" Value="{DynamicResource Brush.Text}" />
+        <Setter Property="FontWeight" Value="Bold" />
+        <Setter Property="HorizontalAlignment" Value="Center" />
+        <Setter Property="VerticalAlignment" Value="Center" />
+    </Style>
+    <Style x:Key="TextBlock.Title" TargetType="{x:Type TextBlock}">
+        <Setter Property="FontSize" Value="{DynamicResource FontSize.Title}" />
+        <Setter Property="FontFamily" Value="{DynamicResource FontFamily.Global}" />
+        <Setter Property="Foreground" Value="{DynamicResource Brush.Text}" />
+        <Setter Property="FontWeight" Value="Bold" />
+        <Setter Property="HorizontalAlignment" Value="Center" />
+        <Setter Property="VerticalAlignment" Value="Center" />
+    </Style>
+    <Style x:Key="TextBlock.Label" TargetType="{x:Type TextBlock}">
+        <Setter Property="FontSize" Value="{DynamicResource FontSize.Label}" />
+        <Setter Property="FontFamily" Value="{DynamicResource FontFamily.Global}" />
+        <Setter Property="Foreground" Value="{DynamicResource Brush.Text}" />
+        <Setter Property="FontWeight" Value="Bold" />
+        <Setter Property="HorizontalAlignment" Value="Center" />
+        <Setter Property="VerticalAlignment" Value="Center" />
     </Style>
 </ResourceDictionary>

+ 2 - 1
SKMC.UI/Styles/TextBox.xaml

@@ -10,13 +10,14 @@
             <Setter Property="VerticalContentAlignment" Value="Center"/>
             <Setter Property="VerticalAlignment" Value="Stretch"/>
             <Setter Property="HorizontalAlignment" Value="Stretch"/>
+            <Setter Property="BorderThickness" Value="1"/>
             <Setter Property="FontSize" Value="12"/>
             <Setter Property="Foreground" Value="{DynamicResource Brush.Text}"/>
             <Setter Property="IconSize" Value="10"/>
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="{x:Type c:SKTextBox}">
-                        <Border BorderThickness="1"
+                        <Border BorderThickness="{TemplateBinding BorderThickness}"
 						        Background="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}"
 						        CornerRadius="{Binding CornerRadius, RelativeSource={RelativeSource TemplatedParent}}"
                                 x:Name="boder">

+ 40 - 13
SKMC.UI/Themes/Dark.xaml

@@ -1,6 +1,5 @@
-<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-    <!--深色主题-->
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+    <!--  深色主题  -->
     <Color x:Key="Color.Background">#1E1E1E</Color>
     <Color x:Key="Color.DarkBackground">#161616</Color>
     <Color x:Key="Color.MachineControls">#121212</Color>
@@ -26,15 +25,36 @@
     <SolidColorBrush x:Key="Brush.PreviewBackground" Color="{DynamicResource Color.PreviewBackground}" />
 
     <SolidColorBrush x:Key="Brush.Button" Color="{DynamicResource Color.Button}" />
-    <SolidColorBrush x:Key="Brush.ButtonPressed" Opacity="0.08" Color="{DynamicResource Color.Overlay}" />
-    <SolidColorBrush x:Key="Brush.ButtonTextInactive" Opacity="0.38" Color="{DynamicResource Color.Text}" />
-    <SolidColorBrush x:Key="Brush.ButtonTextDisabled" Opacity="0.30" Color="{DynamicResource Color.Overlay}" />
-    <SolidColorBrush x:Key="Brush.ButtonHover" Opacity="0.2" Color="{DynamicResource Color.Signature}" />
+    <SolidColorBrush
+        x:Key="Brush.ButtonPressed"
+        Opacity="0.08"
+        Color="{DynamicResource Color.Overlay}" />
+    <SolidColorBrush
+        x:Key="Brush.ButtonTextInactive"
+        Opacity="0.38"
+        Color="{DynamicResource Color.Text}" />
+    <SolidColorBrush
+        x:Key="Brush.ButtonTextDisabled"
+        Opacity="0.30"
+        Color="{DynamicResource Color.Overlay}" />
+    <SolidColorBrush
+        x:Key="Brush.ButtonHover"
+        Opacity="0.2"
+        Color="{DynamicResource Color.Signature}" />
 
-    <SolidColorBrush x:Key="Brush.PrimaryButton" Opacity="0.5" Color="{DynamicResource Color.Signature}" />
-    <SolidColorBrush x:Key="Brush.PrimaryButtonMouseOver" Opacity="0.24" Color="{DynamicResource Color.Signature}" />
+    <SolidColorBrush
+        x:Key="Brush.PrimaryButton"
+        Opacity="0.5"
+        Color="{DynamicResource Color.Signature}" />
+    <SolidColorBrush
+        x:Key="Brush.PrimaryButtonMouseOver"
+        Opacity="0.24"
+        Color="{DynamicResource Color.Signature}" />
     <SolidColorBrush x:Key="Brush.PrimaryButtonPressed" Color="{DynamicResource Color.SignatureDark}" />
-    <SolidColorBrush x:Key="Brush.PrimaryButtonDisabled" Opacity="0.5" Color="{DynamicResource Color.SignatureDark}" />
+    <SolidColorBrush
+        x:Key="Brush.PrimaryButtonDisabled"
+        Opacity="0.5"
+        Color="{DynamicResource Color.SignatureDark}" />
 
     <SolidColorBrush x:Key="Brush.Text" Color="{DynamicResource Color.Text}" />
     <SolidColorBrush x:Key="Brush.TextContrast" Color="{DynamicResource Color.TextContrast}" />
@@ -45,9 +65,16 @@
     <SolidColorBrush x:Key="Brush.Border" Color="{DynamicResource Color.Border}" />
 
     <SolidColorBrush x:Key="Brush.DashboardBackground" Color="{DynamicResource Color.DashboardBackground}" />
-    <SolidColorBrush x:Key="Brush.HeaderAlternative" Color="{DynamicResource Color.HeaderAlternative}"/>
-    <SolidColorBrush x:Key="Brush.BodyAlternative" Color="{DynamicResource Color.BodyAlternative}"/>
-    
+    <SolidColorBrush x:Key="Brush.HeaderAlternative" Color="{DynamicResource Color.HeaderAlternative}" />
+    <SolidColorBrush x:Key="Brush.BodyAlternative" Color="{DynamicResource Color.BodyAlternative}" />
+    <SolidColorBrush
+        x:Key="Brush.PreviewOverlay"
+        Opacity="0.3"
+        Color="{DynamicResource Color.Border}" />
+
+    <SolidColorBrush x:Key="Brush.MotionIO.Default" Color="{DynamicResource Color.DashboardBackground}" />
+    <SolidColorBrush x:Key="Brush.MotionIO.Actived" Color="{DynamicResource Color.Good}" />
+
     <Color x:Key="Color.Signature">#00AFAF</Color>
     <Color x:Key="Color.SignatureLight">#CCEAEC</Color>
     <Color x:Key="Color.SignatureDark">#006D75</Color>

+ 42 - 12
SKMC.UI/Themes/Light.xaml

@@ -1,6 +1,5 @@
-<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-    <!-- 浅色主题 -->
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+    <!--  浅色主题  -->
     <Color x:Key="Color.Background">#FFFFFF</Color>
     <Color x:Key="Color.DarkBackground">#E8F1FA</Color>
     <Color x:Key="Color.MachineControls">#DCDCDC</Color>
@@ -31,15 +30,36 @@
     <SolidColorBrush x:Key="Brush.PreviewBackground" Color="{DynamicResource Color.PreviewBackground}" />
 
     <SolidColorBrush x:Key="Brush.Button" Color="{DynamicResource Color.Button}" />
-    <SolidColorBrush x:Key="Brush.ButtonPressed" Opacity="0.08" Color="{DynamicResource Color.Overlay}" />
-    <SolidColorBrush x:Key="Brush.ButtonTextInactive" Opacity="0.38" Color="{DynamicResource Color.Text}" />
-    <SolidColorBrush x:Key="Brush.ButtonTextDisabled" Opacity="0.30" Color="{DynamicResource Color.Overlay}" />
-    <SolidColorBrush x:Key="Brush.ButtonHover" Opacity="0.2" Color="{DynamicResource Color.Signature}" />
+    <SolidColorBrush
+        x:Key="Brush.ButtonPressed"
+        Opacity="0.08"
+        Color="{DynamicResource Color.Overlay}" />
+    <SolidColorBrush
+        x:Key="Brush.ButtonTextInactive"
+        Opacity="0.38"
+        Color="{DynamicResource Color.Text}" />
+    <SolidColorBrush
+        x:Key="Brush.ButtonTextDisabled"
+        Opacity="0.30"
+        Color="{DynamicResource Color.Overlay}" />
+    <SolidColorBrush
+        x:Key="Brush.ButtonHover"
+        Opacity="0.2"
+        Color="{DynamicResource Color.Signature}" />
 
-    <SolidColorBrush x:Key="Brush.PrimaryButton" Opacity="0.5" Color="{DynamicResource Color.Signature}" />
-    <SolidColorBrush x:Key="Brush.PrimaryButtonMouseOver" Opacity="0.24" Color="{DynamicResource Color.Signature}" />
+    <SolidColorBrush
+        x:Key="Brush.PrimaryButton"
+        Opacity="0.5"
+        Color="{DynamicResource Color.Signature}" />
+    <SolidColorBrush
+        x:Key="Brush.PrimaryButtonMouseOver"
+        Opacity="0.24"
+        Color="{DynamicResource Color.Signature}" />
     <SolidColorBrush x:Key="Brush.PrimaryButtonPressed" Color="{DynamicResource Color.SignatureDark}" />
-    <SolidColorBrush x:Key="Brush.PrimaryButtonDisabled" Opacity="0.5" Color="{DynamicResource Color.SignatureDark}" />
+    <SolidColorBrush
+        x:Key="Brush.PrimaryButtonDisabled"
+        Opacity="0.5"
+        Color="{DynamicResource Color.SignatureDark}" />
 
     <SolidColorBrush x:Key="Brush.Text" Color="{DynamicResource Color.Text}" />
     <SolidColorBrush x:Key="Brush.TextContrast" Color="{DynamicResource Color.TextContrast}" />
@@ -50,8 +70,18 @@
     <SolidColorBrush x:Key="Brush.Border" Color="{DynamicResource Color.Border}" />
 
     <SolidColorBrush x:Key="Brush.DashboardBackground" Color="{DynamicResource Color.DashboardBackground}" />
-    <SolidColorBrush x:Key="Brush.HeaderAlternative" Opacity="0.5" Color="{DynamicResource Color.HeaderAlternative}"/>
-    <SolidColorBrush x:Key="Brush.BodyAlternative" Color="{DynamicResource Color.BodyAlternative}"/>
+    <SolidColorBrush
+        x:Key="Brush.HeaderAlternative"
+        Opacity="0.5"
+        Color="{DynamicResource Color.HeaderAlternative}" />
+    <SolidColorBrush x:Key="Brush.BodyAlternative" Color="{DynamicResource Color.BodyAlternative}" />
+    <SolidColorBrush
+        x:Key="Brush.PreviewOverlay"
+        Opacity="0.5"
+        Color="{DynamicResource Color.SignatureLight}" />
+
+    <SolidColorBrush x:Key="Brush.MotionIO.Default" Color="{DynamicResource Color.DashboardBackground}" />
+    <SolidColorBrush x:Key="Brush.MotionIO.Actived" Color="{DynamicResource Color.DrawCross}" />
 
     <SolidColorBrush x:Key="Brush.Signature" Color="{DynamicResource Color.Signature}" />
     <SolidColorBrush x:Key="Brush.SignatureLight" Color="{DynamicResource Color.SignatureLight}" />

+ 237 - 0
SKMC.UI/UserControls/NumpadControl.xaml

@@ -0,0 +1,237 @@
+<Window x:Class="SKMC.UI.UserControls.NumpadControl"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:SKMC.UI.UserControls"
+        xmlns:c="clr-namespace:SKMC.UI.CustomControls"
+        mc:Ignorable="d"
+        Background="{DynamicResource Brush.Background}"
+        Title="数字键盘" Height="450" Width="350"
+        WindowStartupLocation="CenterScreen"
+        ResizeMode="NoResize">
+    <Window.Resources>
+        <!-- 数字按钮样式 -->
+        <Style x:Key="NumberButtonStyle" TargetType="Button">
+            <Setter Property="FontSize" Value="24"/>
+            <Setter Property="FontWeight" Value="Bold"/>
+            <Setter Property="Background" Value="#FFFFFF"/>
+            <Setter Property="Foreground" Value="#333333"/>
+            <Setter Property="BorderBrush" Value="#CCCCCC"/>
+            <Setter Property="BorderThickness" Value="1"/>
+            <Setter Property="Cursor" Value="Hand"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="Button">
+                        <Border Background="{TemplateBinding Background}"
+                                BorderBrush="{TemplateBinding BorderBrush}"
+                                BorderThickness="{TemplateBinding BorderThickness}"
+                                CornerRadius="5">
+                            <ContentPresenter HorizontalAlignment="Center" 
+                                            VerticalAlignment="Center"/>
+                        </Border>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+            <Style.Triggers>
+                <Trigger Property="IsMouseOver" Value="True">
+                    <Setter Property="Background" Value="#E8E8E8"/>
+                </Trigger>
+                <Trigger Property="IsPressed" Value="True">
+                    <Setter Property="Background" Value="#D0D0D0"/>
+                </Trigger>
+            </Style.Triggers>
+        </Style>
+
+        <!-- 功能按钮样式 -->
+        <Style x:Key="FunctionButtonStyle" TargetType="Button">
+            <Setter Property="FontSize" Value="18"/>
+            <Setter Property="FontWeight" Value="Bold"/>
+            <Setter Property="Background" Value="#4A90D9"/>
+            <Setter Property="Foreground" Value="White"/>
+            <Setter Property="BorderBrush" Value="#4A90D9"/>
+            <Setter Property="BorderThickness" Value="1"/>
+            <Setter Property="Cursor" Value="Hand"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="Button">
+                        <Border Background="{TemplateBinding Background}"
+                                BorderBrush="{TemplateBinding BorderBrush}"
+                                BorderThickness="{TemplateBinding BorderThickness}"
+                                CornerRadius="5">
+                            <ContentPresenter HorizontalAlignment="Center" 
+                                            VerticalAlignment="Center"/>
+                        </Border>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+            <Style.Triggers>
+                <Trigger Property="IsMouseOver" Value="True">
+                    <Setter Property="Background" Value="#3A7BC8"/>
+                </Trigger>
+                <Trigger Property="IsPressed" Value="True">
+                    <Setter Property="Background" Value="#2A6BB8"/>
+                </Trigger>
+            </Style.Triggers>
+        </Style>
+
+        <!-- 危险按钮样式(清空) -->
+        <Style x:Key="DangerButtonStyle" TargetType="Button">
+            <Setter Property="FontSize" Value="20"/>
+            <Setter Property="FontWeight" Value="Bold"/>
+            <Setter Property="Background" Value="#E74C3C"/>
+            <Setter Property="Foreground" Value="White"/>
+            <Setter Property="BorderBrush" Value="#E74C3C"/>
+            <Setter Property="BorderThickness" Value="1"/>
+            <Setter Property="Cursor" Value="Hand"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="Button">
+                        <Border Background="{TemplateBinding Background}"
+                                BorderBrush="{TemplateBinding BorderBrush}"
+                                BorderThickness="{TemplateBinding BorderThickness}"
+                                CornerRadius="5">
+                            <ContentPresenter HorizontalAlignment="Center" 
+                                            VerticalAlignment="Center"/>
+                        </Border>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+            <Style.Triggers>
+                <Trigger Property="IsMouseOver" Value="True">
+                    <Setter Property="Background" Value="#C0392B"/>
+                </Trigger>
+                <Trigger Property="IsPressed" Value="True">
+                    <Setter Property="Background" Value="#A93226"/>
+                </Trigger>
+            </Style.Triggers>
+        </Style>
+
+        <!-- 确认按钮样式 -->
+        <Style x:Key="ConfirmButtonStyle" TargetType="Button">
+            <Setter Property="FontSize" Value="20"/>
+            <Setter Property="FontWeight" Value="Bold"/>
+            <Setter Property="Background" Value="#27AE60"/>
+            <Setter Property="Foreground" Value="White"/>
+            <Setter Property="BorderBrush" Value="#27AE60"/>
+            <Setter Property="BorderThickness" Value="1"/>
+            <Setter Property="Cursor" Value="Hand"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="Button">
+                        <Border Background="{TemplateBinding Background}"
+                                BorderBrush="{TemplateBinding BorderBrush}"
+                                BorderThickness="{TemplateBinding BorderThickness}"
+                                CornerRadius="5">
+                            <ContentPresenter HorizontalAlignment="Center" 
+                                            VerticalAlignment="Center"/>
+                        </Border>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+            <Style.Triggers>
+                <Trigger Property="IsMouseOver" Value="True">
+                    <Setter Property="Background" Value="#219A52"/>
+                </Trigger>
+                <Trigger Property="IsPressed" Value="True">
+                    <Setter Property="Background" Value="#1B8344"/>
+                </Trigger>
+            </Style.Triggers>
+        </Style>
+    </Window.Resources>
+    <Grid Margin="10">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="Auto"/>
+            <RowDefinition Height="Auto"/>
+            <RowDefinition Height="*"/>
+        </Grid.RowDefinitions>
+
+        <!-- 标题 -->
+        <!--<TextBlock Grid.Row="0" Text="Numpad" FontSize="24" 
+                   FontWeight="Bold" HorizontalAlignment="Center" 
+                   Margin="0,0,0,15"
+                   Foreground="{DynamicResource Brush.Text}"/>-->
+
+        <!-- 输入框 -->
+        <c:SKTextBox x:Name="InputTextBox" Grid.Row="1" 
+                     FontSize="28" Height="50" 
+                     VerticalContentAlignment="Center"
+                     TextAlignment="Right"
+                     Margin="0,0,0,15"
+                     IsReadOnly="True"
+                     UnitSize="20"
+                     Style="{StaticResource TextBox.Primary}"/>
+
+        <!-- 数字键盘 -->
+        <Grid Grid.Row="2">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="*"/>
+                <RowDefinition Height="*"/>
+                <RowDefinition Height="*"/>
+                <RowDefinition Height="*"/>
+            </Grid.RowDefinitions>
+
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="*"/>
+                <ColumnDefinition Width="*"/>
+                <ColumnDefinition Width="*"/>
+                <ColumnDefinition Width="*"/>
+            </Grid.ColumnDefinitions>
+
+            <!-- 第一行:7, 8, 9, 清除 -->
+            <Button x:Name="Btn7" Grid.Row="0" Grid.Column="0" 
+                    Content="7" Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+            <Button x:Name="Btn8" Grid.Row="0" Grid.Column="1" 
+                    Content="8" Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+            <Button x:Name="Btn9" Grid.Row="0" Grid.Column="2" 
+                    Content="9" Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+            <Button x:Name="BtnClear" Grid.Row="0" Grid.Column="3" 
+                    Content="C" Style="{StaticResource FunctionButtonStyle}" 
+                    Click="ClearAllButton_Click" Margin="3"/>
+
+            <!-- 第二行:4, 5, 6, 退格 -->
+            <Button x:Name="Btn4" Grid.Row="1" Grid.Column="0" 
+                    Content="4" Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+            <Button x:Name="Btn5" Grid.Row="1" Grid.Column="1" 
+                    Content="5" Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+            <Button x:Name="Btn6" Grid.Row="1" Grid.Column="2" 
+                    Content="6" Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+            <Button x:Name="BtnBackspace" Grid.Row="1" Grid.Column="3" 
+                    Content="⌫" Style="{StaticResource FunctionButtonStyle}" 
+                    Click="BackspaceButton_Click" Margin="3"/>
+
+            <!-- 第三行:1, 2, 3, 复制 -->
+            <Button x:Name="Btn1" Grid.Row="2" Grid.Column="0" 
+                    Content="1" Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+            <Button x:Name="Btn2" Grid.Row="2" Grid.Column="1" 
+                    Content="2" Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+            <Button x:Name="Btn3" Grid.Row="2" Grid.Column="2" 
+                    Content="3" Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+
+            <!-- 第四行:0, 小数点, +/-号, 粘贴 -->
+            <Button x:Name="Btn0" Grid.Row="3" Grid.Column="0" 
+                    Content="0" Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+            <Button x:Name="BtnDecimal" Grid.Row="3" Grid.Column="1" 
+                    Content="." Style="{StaticResource NumberButtonStyle}" 
+                    Click="NumberButton_Click" Margin="3"/>
+            <Button x:Name="BtnSign" Grid.Row="2" Grid.Column="3" 
+                    Content="+/-" Style="{StaticResource FunctionButtonStyle}" 
+                    Click="SignButton_Click" Margin="3"/>
+
+            <!-- 第五行:清空,确认 -->
+            <Button x:Name="BtnConfirm" Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" 
+                    Content="确认" Style="{StaticResource ConfirmButtonStyle}" 
+                    Click="ConfirmButton_Click" Margin="3"/>
+        </Grid>
+    </Grid>
+</Window>

+ 277 - 0
SKMC.UI/UserControls/NumpadControl.xaml.cs

@@ -0,0 +1,277 @@
+using SKMC.UI.CustomControls;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace SKMC.UI.UserControls
+{
+    /// <summary>
+    /// NumpadControl.xaml 的交互逻辑
+    /// </summary>
+    public partial class NumpadControl : Window
+    {
+        // 存储输入结果的属性
+        public string InputResult { get; private set; }
+        public bool IsConfirmed { get; private set; }
+
+        // 目标TextBox引用
+        private SKTextBox _targetTextBox;
+
+        public NumpadControl(SKTextBox targetTextBox = null)
+        {
+            InitializeComponent();
+            _targetTextBox = targetTextBox;
+            InputTextBox.Unit = targetTextBox.Unit;
+            // 如果有目标TextBox,加载其内容
+            if (_targetTextBox != null && !string.IsNullOrEmpty(_targetTextBox.Text))
+            {
+                InputTextBox.Text = _targetTextBox.Text;
+            }
+            else
+            {
+                InputTextBox.Text = "0";
+            }
+
+            IsConfirmed = false;
+            InputResult = InputTextBox.Text;
+
+            // 设置窗口位置在目标TextBox附近
+            if (_targetTextBox != null)
+            {
+                var window = Application.Current.MainWindow;
+                if (window != null)
+                {
+                    this.Owner = window;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 单位
+        /// </summary>
+        public string Unit
+        {
+            get { return (string)GetValue(UnitProperty); }
+            set { SetValue(UnitProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for Unit.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty UnitProperty =
+            DependencyProperty.Register(nameof(Unit), typeof(string), typeof(NumpadControl), new PropertyMetadata(""));
+
+
+
+        // 数字按钮点击事件
+        private void NumberButton_Click(object sender, RoutedEventArgs e)
+        {
+            if (sender is Button button)
+            {
+                string content = button.Content.ToString();
+                string currentText = InputTextBox.Text;
+
+                bool isNegative = currentText.StartsWith("-");
+                string numberPart = isNegative ? currentText.Substring(1) : currentText;
+
+                if (string.IsNullOrEmpty(numberPart) || numberPart == "0")
+                {
+                    if (content != ".")
+                    {
+                        numberPart = content;
+                    }
+                    else
+                    {
+                        numberPart = "0.";
+                    }
+                }
+                else
+                {
+                    if (content == "." && numberPart.Contains("."))
+                    {
+                        return;
+                    }
+
+                    if (numberPart.Length >= 20)
+                    {
+                        return;
+                    }
+
+                    numberPart += content;
+                }
+
+                InputTextBox.Text = isNegative ? "-" + numberPart : numberPart;
+                InputTextBox.CaretIndex = InputTextBox.Text.Length;
+            }
+        }
+
+        // 正负号切换
+        private void SignButton_Click(object sender, RoutedEventArgs e)
+        {
+            if (string.IsNullOrEmpty(InputTextBox.Text) || InputTextBox.Text == "0")
+            {
+                InputTextBox.Text = "0";
+                return;
+            }
+
+            string currentText = InputTextBox.Text;
+
+            if (currentText.StartsWith("-"))
+            {
+                string positiveNumber = currentText.Substring(1);
+                if (string.IsNullOrEmpty(positiveNumber) || positiveNumber == "0")
+                {
+                    InputTextBox.Text = "0";
+                }
+                else
+                {
+                    InputTextBox.Text = positiveNumber;
+                }
+            }
+            else
+            {
+                if (currentText == "0")
+                {
+                    return;
+                }
+                InputTextBox.Text = "-" + currentText;
+            }
+
+            InputTextBox.CaretIndex = InputTextBox.Text.Length;
+        }
+
+        // 清除按钮
+        private void ClearButton_Click(object sender, RoutedEventArgs e)
+        {
+            if (!string.IsNullOrEmpty(InputTextBox.Text))
+            {
+                string currentText = InputTextBox.Text;
+
+                if ((currentText.StartsWith("-") && currentText.Length == 1) ||
+                    currentText.Length == 1)
+                {
+                    InputTextBox.Text = "0";
+                }
+                else
+                {
+                    InputTextBox.Text = currentText.Substring(0, currentText.Length - 1);
+
+                    if (InputTextBox.Text == "-")
+                    {
+                        InputTextBox.Text = "0";
+                    }
+                }
+
+                InputTextBox.CaretIndex = InputTextBox.Text.Length;
+            }
+            else
+            {
+                InputTextBox.Text = "0";
+            }
+        }
+
+        // 退格键
+        private void BackspaceButton_Click(object sender, RoutedEventArgs e)
+        {
+            ClearButton_Click(sender, e);
+        }
+
+        // 清空所有
+        private void ClearAllButton_Click(object sender, RoutedEventArgs e)
+        {
+            InputTextBox.Text = "0";
+        }
+
+        // 确认按钮
+        private void ConfirmButton_Click(object sender, RoutedEventArgs e)
+        {
+            InputResult = InputTextBox.Text;
+            IsConfirmed = true;
+
+            // 更新目标TextBox
+            if (_targetTextBox != null)
+            {
+                _targetTextBox.Text = InputResult;
+            }
+
+            this.DialogResult = true;
+            this.Close();
+        }
+
+        // 取消按钮
+        private void CancelButton_Click(object sender, RoutedEventArgs e)
+        {
+            IsConfirmed = false;
+            this.DialogResult = false;
+            this.Close();
+        }
+
+        // 键盘快捷键支持
+        protected override void OnKeyDown(KeyEventArgs e)
+        {
+            base.OnKeyDown(e);
+
+            if (e.Key >= Key.D0 && e.Key <= Key.D9)
+            {
+                string digit = e.Key.ToString().Substring(1);
+                var button = FindName($"Btn{digit}") as Button;
+                if (button != null)
+                {
+                    NumberButton_Click(button, new RoutedEventArgs());
+                }
+                e.Handled = true;
+            }
+            else if (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9)
+            {
+                string digit = e.Key.ToString().Substring(6);
+                var button = FindName($"Btn{digit}") as Button;
+                if (button != null)
+                {
+                    NumberButton_Click(button, new RoutedEventArgs());
+                }
+                e.Handled = true;
+            }
+            else if (e.Key == Key.Decimal || e.Key == Key.OemPeriod)
+            {
+                NumberButton_Click(BtnDecimal, new RoutedEventArgs());
+                e.Handled = true;
+            }
+            else if (e.Key == Key.Back)
+            {
+                ClearButton_Click(this, new RoutedEventArgs());
+                e.Handled = true;
+            }
+            else if (e.Key == Key.Delete)
+            {
+                ClearAllButton_Click(this, new RoutedEventArgs());
+                e.Handled = true;
+            }
+            else if (e.Key == Key.C && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
+            {
+                e.Handled = true;
+            }
+            else if (e.Key == Key.V && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
+            {
+                e.Handled = true;
+            }
+            else if (e.Key == Key.Enter)
+            {
+                ConfirmButton_Click(this, new RoutedEventArgs());
+                e.Handled = true;
+            }
+            else if (e.Key == Key.Escape)
+            {
+                CancelButton_Click(this, new RoutedEventArgs());
+                e.Handled = true;
+            }
+        }
+
+        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
+        {
+            // 如果没有确认,返回原始内容
+            if (!IsConfirmed && _targetTextBox != null)
+            {
+                // 保持原内容不变
+            }
+            base.OnClosing(e);
+        }
+    }
+}