• 如何为WPF应用程序制作一个虚拟键盘?这里有答案(Part 2)


    Telerik UI for WPF拥有超过100个控件来创建美观、高性能的桌面应用程序,同时还能快速构建企业级办公WPF应用程序。UI for WPF支持MVVM、触摸等,创建的应用程序可靠且结构良好,非常容易维护,其直观的API将无缝地集成Visual Studio工具箱中。

    在上文中,小编为大家介绍了虚拟键盘的用途、主要的一些功能等(点击这里回顾>>),本文将继续为大家介绍如何为WPF应用程序制作一个虚拟键盘。

    点击获取Telerik UI for WPF 最新版下载

    主要功能

    自定义

    你觉得组件的默认外观太标准了?可以使用控件的 VirtualKeayboardTemplateSelector 属性自定义键盘按钮,让键盘与众不同!

    1. <ResourceDictionary>
    2. <ResourceDictionary.MergedDictionaries>
    3. <ResourceDictionary Source="/Telerik.Windows.Themes.Crystal;component/Themes/System.Windows.xaml"/>
    4. <ResourceDictionary Source="/Telerik.Windows.Themes.Crystal;component/Themes/Telerik.Windows.Controls.xaml"/>
    5. <ResourceDictionary Source="/Telerik.Windows.Themes.Crystal;component/Themes/Telerik.Windows.Controls.Input.xaml"/>
    6. <ResourceDictionary Source="/Telerik.Windows.Themes.Crystal;component/Themes/Telerik.Windows.Controls.Navigation.xaml"/>
    7. ResourceDictionary.MergedDictionaries>
    8. <Style x:Key="KeyButtonStyle" TargetType="telerik:RadButton" BasedOn="{StaticResource RadButtonStyle}">
    9. <Setter Property="Padding" Value="4"/>
    10. <Setter Property="FontSize" Value="11"/>
    11. <Setter Property="Focusable" Value="False"/>
    12. <Setter Property="Foreground" Value="#4b6159"/>
    13. <Setter Property="CornerRadius" Value="20"/>
    14. <Setter Property="MinWidth" Value="0"/>
    15. Style>
    16. <DataTemplate x:Key="RegularKeyTemplate">
    17. <telerik:RadButton Command="{Binding KeyCommand}" AutomationProperties.AutomationId="{Binding DisplayText}" Style="{StaticResource KeyButtonStyle}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch">
    18. <Grid>
    19. <Grid.RowDefinitions>
    20. <RowDefinition/>
    21. <RowDefinition/>
    22. Grid.RowDefinitions>
    23. <Grid.ColumnDefinitions>
    24. <ColumnDefinition/>
    25. <ColumnDefinition/>
    26. Grid.ColumnDefinitions>
    27. <TextBlock Text="{Binding ShiftText}" Margin="3 0 0 0" Grid.Row="0" Grid.Column="0" Visibility="{Binding ShowSecondaryText, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    28. <TextBlock Text="{Binding DisplayText}" Grid.RowSpan="2" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    29. Grid>
    30. telerik:RadButton>
    31. DataTemplate>
    32. <DataTemplate x:Key="SpecialKeyTemplate">
    33. <telerik:RadButton Content="{Binding DisplayText}" Command="{Binding KeyCommand}" AutomationProperties.AutomationId="{Binding DisplayText}" Style="{StaticResource KeyButtonStyle}" Background="#ffdac1" MinWidth="40" />
    34. DataTemplate>
    35. <DataTemplate x:Key="NumpadKeyTemplate">
    36. <telerik:RadButton Content="{Binding DisplayText}" Command="{Binding KeyCommand}" AutomationProperties.AutomationId="{Binding DisplayText}" Style="{StaticResource KeyButtonStyle}"/>
    37. DataTemplate>
    38. <DataTemplate x:Key="LockKeyTemplate">
    39. <telerik:RadToggleButton Foreground="#4b6159" Content="{Binding DisplayText}" Command="{Binding KeyCommand}" IsChecked="{Binding IsChecked}" Background="#b5ead7"
    40. AutomationProperties.AutomationId="{Binding DisplayText}" Focusable="False" FontSize="{Binding FontSize, RelativeSource={RelativeSource AncestorType={x:Type telerikNavigation:RadVirtualKeyboard}}}"
    41. Padding="0" helpers:ThemeHelper.CornerRadius="30" helpers:ThemeHelper.FocusVisualMargin="0"/>
    42. DataTemplate>
    43. <telerikNavigation:VirtualKeyboardTemplateSelector x:Key="VirtualKeyboardTemplateSelector"
    44. RegularTemplate="{StaticResource RegularKeyTemplate}"
    45. SpecialTemplate="{StaticResource SpecialKeyTemplate}"
    46. NumpadTemplate="{StaticResource NumpadKeyTemplate}"
    47. LockTemplate="{StaticResource LockKeyTemplate}" />
    48. ResourceDictionary>

    让我们来看看:

    这还不是全部,通过扩展控件的视图模型和可在 VirtualKeyboardTemplateSelector 的 DataTemplates 中使用的其他属性,可以将控件的自定义提升到一个新的水平。您可以将需要实现自定义键的工厂类使用扩展视图模型,现在将演示如何为按钮的背景和前景添加属性。

    1. 我们需要创建一个自定义键视图模型来包含背景和前景信息:

    1. public class CustomLockKeyViewModel : LockKeyViewModel
    2. {
    3. public CustomLockKeyViewModel(int virtualKey, double keyWidth, double keyHeight, string displayText)
    4. : base(virtualKey, keyWidth, keyHeight, displayText)
    5. {
    6. }
    7. public Brush Background { get; set; }
    8. public Brush Foreground { get; set; }
    9. }
    10. public class CustomModifierKeyViewModel : ModifierKeyViewModel
    11. {
    12. public CustomModifierKeyViewModel(int virtualKey, double keyWidth, double keyHeight, string displayText)
    13. : base(virtualKey, keyWidth, keyHeight, displayText)
    14. {
    15. }
    16. public Brush Background { get; set; }
    17. public Brush Foreground { get; set; }
    18. }
    19. public class CustomRegularKeyViewModel : RegularKeyViewModel
    20. {
    21. public CustomRegularKeyViewModel(int virtualKey, double keyWidth, double keyHeight, bool showSecondaryText, string displayText = null)
    22. : base(virtualKey, keyWidth, keyHeight, showSecondaryText, displayText)
    23. {
    24. }
    25. public Brush Background { get; set; }
    26. public Brush Foreground { get; set; }
    27. }
    28. public class CustomSpecialKeyViewModel : SpecialKeyViewModel
    29. {
    30. public CustomSpecialKeyViewModel(int virtualKey, double keyWidth, double keyHeight, string displayText)
    31. : base(virtualKey, keyWidth, keyHeight, displayText)
    32. {
    33. }
    34. public Brush Background { get; set; }
    35. public Brush Foreground { get; set; }
    36. }

    2. 下一步是创建一个密钥因素:

    1. public class CustomKeyFactory : DefaultKeyFactory
    2. {
    3. private static readonly List<int> specialColorKeyCodes = new List<int>()
    4. {
    5. 8, 20, /*CapsLock*/ 9, /*tilde*/ 160,
    6. /*Backspace*/ 226, 162, /*Ctrl*/
    7. 91, /*Win*/ 164, /*Alt*/ 165, /*AltGr*/ 93, /*Menu*/
    8. 163, /*Ctrl*/ 45, /*Backspace*/ 226, 192
    9. };
    10. public Brush DefaultBrush { get; set; }
    11. public Brush EnterBrush { get; set; }
    12. public Brush SpaceBrush { get; set; }
    13. public Brush SpecialBrush { get; set; }
    14. public Brush ShiftBrush { get; set; }
    15. public Brush DefaultForeground { get; set; }
    16. public CustomKeyFactory()
    17. {
    18. DefaultBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FCFCFC"));
    19. EnterBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#F2E50B"));
    20. SpaceBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF7F50"));
    21. SpecialBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#21B20C"));
    22. ShiftBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#17DEEE"));
    23. DefaultForeground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#333333"));
    24. }
    25. public override BaseKeyViewModel CreateKey(int virtualKey, KeyType keyType = KeyType.Normal, string displayText = null, double width = 1, double height = 1, int alternateVirtualKey = -1, string alternateText = null, bool showSecondaryText = false)
    26. {
    27. var keyModel = CreateCustomKey(virtualKey, keyType, displayText, width, height, alternateVirtualKey, alternateText, showSecondaryText);
    28. if (virtualKey == 13) // Enter
    29. {
    30. SetCustomViewModelProperty(keyModel, "Background", EnterBrush);
    31. SetCustomViewModelProperty(keyModel, "Foreground", Brushes.Black);
    32. }
    33. if (virtualKey == 13) // Enter
    34. {
    35. SetCustomViewModelProperty(keyModel, "Background", EnterBrush);
    36. SetCustomViewModelProperty(keyModel, "Foreground", Brushes.Black);
    37. }
    38. else if (virtualKey == 32) // Space
    39. {
    40. SetCustomViewModelProperty(keyModel, "Background", SpaceBrush);
    41. }
    42. else if (virtualKey == 160 || virtualKey == 161) // Shift
    43. {
    44. SetCustomViewModelProperty(keyModel, "Background", ShiftBrush);
    45. }
    46. else if (specialColorKeyCodes.Contains(virtualKey))
    47. {
    48. SetCustomViewModelProperty(keyModel, "Background", SpecialBrush);
    49. SetCustomViewModelProperty(keyModel, "Foreground", Brushes.White);
    50. }
    51. return keyModel;
    52. }
    53. private BaseKeyViewModel CreateCustomKey(int virtualKey, KeyType keyType, string displayText, double width, double height, int alternateVirtualKey, string alternateText, bool showSecondaryText)
    54. {
    55. switch (keyType)
    56. {
    57. case KeyType.Normal:
    58. return new CustomRegularKeyViewModel(virtualKey, width, height, showSecondaryText, displayText) { Background = DefaultBrush, Foreground = DefaultForeground };
    59. case KeyType.Special:
    60. return new CustomSpecialKeyViewModel(virtualKey, width, height, displayText) { Background = DefaultBrush, Foreground = DefaultForeground };
    61. case KeyType.Modifier:
    62. return new CustomLockKeyViewModel(virtualKey, width, height, displayText) { Background = DefaultBrush, Foreground = DefaultForeground };
    63. case KeyType.Lock:
    64. return new CustomLockKeyViewModel(virtualKey, width, height, displayText) { Background = DefaultBrush, Foreground = DefaultForeground };
    65. case KeyType.Numpad:
    66. return new NumpadKeyViewModel(virtualKey, width, height, displayText, alternateVirtualKey, alternateText);
    67. default:
    68. throw new ArgumentException("Unknown key type");
    69. }
    70. }
    71. private static void SetCustomViewModelProperty(BaseKeyViewModel viewModel, string propertyName, object value)
    72. {
    73. var propertyInfo = viewModel.GetType().GetProperty(propertyName);
    74. if (propertyInfo != null)
    75. {
    76. propertyInfo.SetValue(viewModel, value);
    77. }
    78. }
    79. }

    3. 现在我们将定义键模板选择器:

    1. <telerik:VirtualKeyboardTemplateSelector x:Key="KeyTemplateSelector">
    2. <telerik:VirtualKeyboardTemplateSelector.RegularTemplate>
    3. <DataTemplate>
    4. <telerik:RadButton Command="{Binding KeyCommand}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" Padding="0" Background="{Binding Background}" Foreground="{Binding Foreground}">
    5. <Grid>
    6. <Grid.RowDefinitions>
    7. <RowDefinition/>
    8. <RowDefinition/>
    9. Grid.RowDefinitions>
    10. <Grid.ColumnDefinitions>
    11. <ColumnDefinition/>
    12. <ColumnDefinition/>
    13. Grid.ColumnDefinitions>
    14. <TextBlock Text="{Binding ShiftText}" Margin="3 0 0 0" Visibility="{Binding ShowSecondaryText, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    15. <TextBlock Text="{Binding DisplayText}" Grid.RowSpan="2" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    16. Grid>
    17. telerik:RadButton>
    18. DataTemplate>
    19. telerik:VirtualKeyboardTemplateSelector.RegularTemplate>
    20. <telerik:VirtualKeyboardTemplateSelector.SpecialTemplate>
    21. <DataTemplate>
    22. <telerik:RadButton Content="{Binding DisplayText}" Command="{Binding KeyCommand}" Padding="0" Background="{Binding Background}" Foreground="{Binding Foreground}"/>
    23. DataTemplate>
    24. telerik:VirtualKeyboardTemplateSelector.SpecialTemplate>
    25. <telerik:VirtualKeyboardTemplateSelector.LockTemplate>
    26. <DataTemplate>
    27. <telerik:RadToggleButton Content="{Binding DisplayText}" Command="{Binding KeyCommand}" IsChecked="{Binding IsChecked}" Background="{Binding Background}" Foreground="{Binding Foreground}"/>
    28. DataTemplate>
    29. telerik:VirtualKeyboardTemplateSelector.LockTemplate>
    30. telerik:VirtualKeyboardTemplateSelector>

    4. 最后一步是设置自定义密钥因素和模板选择器:

    1. <telerik:RadVirtualKeyboard VirtualKeyboardTemplateSelector="{StaticResource KeyTemplateSelector}" DefaultKeyboardLayout="Compact" Width="675" Height="240">
    2. <telerik:RadVirtualKeyboard.KeyFactory>
    3. <local:CustomKeyFactory />
    4. telerik:RadVirtualKeyboard.KeyFactory>
    5. telerik:RadVirtualKeyboard>

  • 相关阅读:
    浅谈二叉树
    vue之sourcemap
    Haproxy负载均衡集群
    穿越时空,探索未来的云计算世界
    物联网AI MicroPython传感器学习 之 GC7219点阵屏驱动模块
    智能驾驶电子地图路侧分发机制
    深度学习基础:循环神经网络中的长期依赖问题
    说说你对js作用域的理解 相关题
    二极管:Irush与我何干?
    《Linux驱动:块设备的读写流程( ll_rw_block 接口分析)》
  • 原文地址:https://blog.csdn.net/AABBbaby/article/details/126758812