原文:工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox

1. 背景

  因为最近在使用wpf开发桌面端应用,在查看页面需要把TextBox和Combox等控件设置为只读的。原本是个很简单的事,设置属性IsReadOnly="True"或IsEnabled="False"就可以解决了,可是产品觉得样式不是他想要的(背景是灰色的),想要实现的效果是和编辑时的样式一致,仅仅是不可编辑而已。我想这也简单啊,强制修改背景色和字体就完事了,结果发现TextBox修改背景色是可行的,但是修改后字体是灰色的,改也改不了,Combox更是连背景色都改不了。。。wtf

  于是开始了一段Google之路,发现别人说的都好复杂,大概明白了修改自带的不可编辑或只读的样式不是一件简单的事。于是我准备用一种变通的方法来解决这个问题,写个自定义控件,通过设置自定义控件的属性来显示/隐藏内部控件的方式。

2. 实现

  首先新建一个用户控件(UserControl),命名为LabelRenderTextBox,在LabelRenderTextBox.xaml文件编写以下内容 

  1.   <!--DataContext="{Binding RelativeSource={RelativeSource self}} datacontext绑定自身会破坏binding链,而通过第一个child来binding则不会破坏"-->
  2.   <StackPanel x:Name="panel" DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:LabelRenderTextBox}}">
  3. <Border BorderThickness="1" BorderBrush="#ccc" x:Name="label" Width="{Binding ElementName=panel, Path=ActualWidth}" Height="24" Visibility="Collapsed" Padding="5,3,0,0">
  4. <TextBlock Text="{Binding Text}" ></TextBlock>
  5. </Border>
  6. <TextBox x:Name="textbox" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="{Binding ElementName=panel, Path=ActualWidth}" Height="24"
  7. base:CustomizeProperty.Placeholder="{Binding Placeholder}" TextChanged="Textbox_TextChanged" ></TextBox>
  8. </StackPanel>

  如图,panel是UserControl内部最外层的元素,把这里的DataContext设为自身,就可以把内部控件的属性和cs文件中的属性进行绑定。label是默认隐藏的元素,textbox是默认显示的控件。label和textbox的Text属性都是绑定的LabelRenderTextBox的Text属性,宽度都是和最外层的panel的宽度进行绑定的,以便于使用者自己设置宽度。

  那么当我们使用LabelRenderTextBox控件进行编辑的时候,实际上还是通过TextBox来实现了,因为设置了Mode=TwoWay进行了双向绑定,UpdateSourceTrigger=PropertyChanged,所以当TextBox的Text改变时,LabelRenderTextBox的Text值也会跟着改变,所以我们可以在LabelRenderTextBox.cs文件里添加一个属性 public string Text { get; set; } ,可是当我们在外部直接修改LabelRenderTextBox的Text值如何使内部的TextBox值也跟着改变呢?这时候就需要用到wpf的依赖属性了,首先通过查看UserControl的继承关系可以发现UserControl是继承自DependencyObject的,意味着它是一个依赖对象,可以设置依赖属性。所以我们可以在LabelRenderTextBox.cs文件里添加以下代码:

  1. public string Text { get
  2. {
  3. return (string)this.GetValue(TextProperty);
  4. }
  5. set
  6. {
  7. this.SetValue(TextProperty, value);
  8. }
  9. }
  10.  
  11. public static readonly DependencyProperty TextProperty =
  12. DependencyProperty.RegisterAttached("Text", typeof(string), typeof(LabelRenderTextBox), new PropertyMetadata("", OnTextChanged));
  13.  
  14. private static void OnTextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  15. {
  16. var element = obj as LabelRenderTextBox;
  17. if (element != null)
  18. {
  19. element.Text = e.NewValue as string;
  20. }
  21. }

  通过DependencyProperty.RegisterAttached方法注册一个Text属性,string类型的,类型为LabelRenderTextBox,PropertyMetadata的第一个参数是默认值,第二个参数是一个回调函数(当属性改变时进行回调),回调时通过Text的set方法来调用SetValue属性来设置依赖属性的值并通知与其绑定的属性(想知道如何实现的可以参考:WPF依赖对象(DependencyObject) 实现源码,理解WPF原理必读)。

  接下来,定义一个枚举类来列举出需要的编辑模式,我这里列举出4种模式,可根据自己的需求进行调整。

  1. public enum EditModes
  2. {
  3. //编辑模式
  4. Editable = 0,
  5. //只读模式
  6. ReadOnly = 1,
  7. //只读模式展示,单击进入编辑模式,失去焦点后恢复只读模式
  8. Click = 2,
  9. //只读模式展示,双击进入编辑模式,失去焦点后恢复只读模式
  10. DoubleCLick = 3
  11. }

  定义了枚举之后就要使用了,和设置Text属性的方式来注册一个EditMode依赖属性,SetEditable方法传入true/false来设置textbox(编辑)和label(只读)的显示和隐藏。这样只要通过设置EditMode属性就可以完美实现产品的需求了,我真棒!

  1.   #region EditModeProperty
  2. public EditModes EditMode {
  3. get { return (EditModes)this.GetValue(EditModeProperty); }
  4. set {
  5. this.SetValue(EditModeProperty, value);
  6. if (value == EditModes.Editable)
  7. {
  8. SetEditable(true);
  9. }
  10. else
  11. {
  12. SetEditable(false);
  13. }
  14. }
  15. }
  16.  
  17. public static readonly DependencyProperty EditModeProperty =
  18. DependencyProperty.RegisterAttached("EditMode", typeof(EditModes), typeof(LabelRenderTextBox), new PropertyMetadata(EditModes.Editable, OnEditModeChanged));
  19.  
  20. private static void OnEditModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  21. {
  22. var element = obj as LabelRenderTextBox;
  23. if (element != null)
  24. {
  25. element.EditMode = (EditModes)e.NewValue;
  26. }
  27. }
  28. #endregion
  29.  
  30. private void SetEditable(bool editable)
  31. {
  32. if (editable)
  33. {
  34. this.label.Visibility = Visibility.Collapsed;
  35. this.textbox.Visibility = Visibility.Visible;
  36. }
  37. else
  38. {
  39. this.label.Visibility = Visibility.Visible;
  40. this.textbox.Visibility = Visibility.Collapsed;
  41. }
  42. }

  可是按照产品的需求只要Editable和ReadOnly两个属性就够了,其他两个是用来扩展的,可以在合适的场景下带来更好的用户体验,默认展示只读模式,单击或者双击变为编辑模式,失去焦点后恢复只读模式。实现方法也很简单,直接在UserControl定义几个事件,在对应的事件函数进行如下处理。

  1.    private void Click(object sender, MouseButtonEventArgs e)
  2. {
  3. if (EditMode == EditModes.Click)
  4. SetEditable(true);
  5. }
  6.  
  7. private void DoubleClick(object sender, MouseButtonEventArgs e)
  8. {
  9. if (EditMode == EditModes.DoubleCLick)
  10. SetEditable(true);
  11. }
  12.  
  13. private void Lost_Focus(object sender, RoutedEventArgs e)
  14. {
  15. if(EditMode == EditModes.DoubleCLick || EditMode == EditModes.Click)
  16. SetEditable(false);
  17. }

  你可能会想,如果想监听TextBox的事件该怎么做呢,也很简单,在cs文件里定义相同的事件,然后在cs文件里监听对应事件,触发时调用定义的事件即可。

  1. public event TextChangedEventHandler TextChanged;
  2.  
  3. private void Textbox_TextChanged(object sender, TextChangedEventArgs e)
  4. {
  5. this.TextChanged?.Invoke(this, e);
  6. }

  是不是很简单呢?希望可以帮到遇到相同问题的朋友,完整代码如下:

  1. <UserControl x:Class="YZ.HIS.UserControls.LabelRenders.LabelRenderTextBox"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  6. xmlns:base="clr-namespace:APP_YFT.Base;assembly=APP-YFT.Base"
  7. xmlns:local="clr-namespace:YZ.HIS.UserControls.LabelRenders"
  8. mc:Ignorable="d" BorderThickness="0"
  9. Height="24" d:DesignWidth="80" PreviewMouseLeftButtonDown="Click" PreviewMouseDoubleClick="DoubleClick"
  10. LostFocus="Lost_Focus">
  11. <UserControl.Resources>
  12. <Style x:Key="mySearchTextBoxStyle" TargetType="{x:Type TextBox}">
  13. <Setter Property="VerticalContentAlignment" Value="Center"/>
  14. <Setter Property="Padding" Value="6,0,0,0"/>
  15. <Setter Property="Template">
  16. <Setter.Value>
  17. <ControlTemplate TargetType="{x:Type TextBox}">
  18. <Border x:Name="bdRoot"
  19. BorderBrush="{TemplateBinding BorderBrush}"
  20. BorderThickness="{TemplateBinding BorderThickness}"
  21. SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
  22. Background="{TemplateBinding Background}">
  23. <DockPanel LastChildFill="True">
  24. <Button x:Name="ClearButton"
  25. DockPanel.Dock="Right"
  26. Focusable="False" Click="ExecCleanSearchText"
  27. Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
  28. FontSize="{TemplateBinding FontSize}">
  29. <Button.Template>
  30. <ControlTemplate>
  31. <Image x:Name="Image" Source="/YZ.HIS;component/Images/tbClean_icon.png" Stretch="None"/>
  32. </ControlTemplate>
  33. </Button.Template>
  34. </Button>
  35. <ScrollViewer x:Name="PART_ContentHost" DockPanel.Dock="Left" Background="{TemplateBinding Background}"/>
  36. </DockPanel>
  37. </Border>
  38. <ControlTemplate.Triggers>
  39. <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
  40. <Setter TargetName="ClearButton" Property="Visibility" Value="Collapsed" />
  41. </DataTrigger>
  42. <Trigger Property="IsFocused" Value="True">
  43. <Setter TargetName="bdRoot" Property="BorderBrush" Value="#569DE5"/>
  44. </Trigger>
  45. <Trigger Property="IsMouseOver" Value="True">
  46. <Setter TargetName="bdRoot" Property="BorderBrush" Value="#7EB4EA"/>
  47. </Trigger>
  48. </ControlTemplate.Triggers>
  49. </ControlTemplate>
  50. </Setter.Value>
  51. </Setter>
  52. </Style>
  53. </UserControl.Resources>
  54. <!--DataContext="{Binding RelativeSource={RelativeSource self}} datacontext绑定自身会破坏binding链,而通过第一个child来binding则不会破坏"-->
  55. <StackPanel x:Name="panel" DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:LabelRenderTextBox}}">
  56. <Border BorderThickness="1" BorderBrush="#ccc" x:Name="label" Width="{Binding ElementName=panel, Path=ActualWidth}" Height="24" Visibility="Collapsed" Padding="5,3,0,0">
  57. <TextBlock Text="{Binding Text}" ></TextBlock>
  58. </Border>
  59. <TextBox x:Name="textbox" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="{Binding ElementName=panel, Path=ActualWidth}" Height="24"
  60. base:CustomizeProperty.Placeholder="{Binding Placeholder}" TextChanged="Textbox_TextChanged" ></TextBox>
  61. </StackPanel>
  62. </UserControl>

xaml

  1. using APP_YFT.Base;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Data;
  11. using System.Windows.Documents;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. using System.Windows.Media.Imaging;
  15. using System.Windows.Navigation;
  16. using System.Windows.Shapes;
  17.  
  18. namespace YZ.HIS.UserControls.LabelRenders
  19. {
  20. /// <summary>
  21. /// LabelRenderTextBox.xaml 的交互逻辑
  22. /// </summary>
  23. public partial class LabelRenderTextBox : UserControl
  24. {
  25. public LabelRenderTextBox()
  26. {
  27. InitializeComponent();
  28. }
  29.  
  30. #region events
  31. public event TextChangedEventHandler TextChanged;
  32.  
  33. private void Textbox_TextChanged(object sender, TextChangedEventArgs e)
  34. {
  35. if (RequiredValue == RequiredValues.Number)
  36. {
  37. TextBox textBox = sender as TextBox;
  38. string text = textBox.Text;
  39. Regex reg = new Regex(@"^[0-9]*$");
  40. if (text == null || (text.Count() == 0) || !reg.IsMatch(text))
  41. {
  42. textBox.Text = "";
  43. return;
  44. }
  45. }
  46. this.TextChanged?.Invoke(this, e);
  47. }
  48.  
  49. //清空输入框事件
  50. private void ExecCleanSearchText(object sender, RoutedEventArgs e)
  51. {
  52. Button btn = sender as Button;
  53. if (btn == null)
  54. return;
  55. TextBox tb = btn.TemplatedParent as TextBox;
  56. if (tb != null)
  57. {
  58. tb.Text = "";
  59. }
  60. }
  61.  
  62. private void Click(object sender, MouseButtonEventArgs e)
  63. {
  64. if (EditMode == EditModes.Click)
  65. SetEditable(true);
  66. }
  67.  
  68. private void DoubleClick(object sender, MouseButtonEventArgs e)
  69. {
  70. if (EditMode == EditModes.DoubleCLick)
  71. SetEditable(true);
  72. }
  73.  
  74. private void Lost_Focus(object sender, RoutedEventArgs e)
  75. {
  76. if(EditMode == EditModes.DoubleCLick || EditMode == EditModes.Click)
  77. SetEditable(false);
  78. }
  79. #endregion
  80.  
  81. #region TextProperty
  82. //public string Text { get; set; }
  83. public string Text { get
  84. {
  85. return (string)this.GetValue(TextProperty);
  86. }
  87. set
  88. {
  89. this.SetValue(TextProperty, value);
  90. }
  91. }
  92.  
  93. public static readonly DependencyProperty TextProperty =
  94. DependencyProperty.RegisterAttached("Text", typeof(string), typeof(LabelRenderTextBox), new PropertyMetadata("", OnTextChanged));
  95.  
  96. private static void OnTextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  97. {
  98. var element = obj as LabelRenderTextBox;
  99. if (element != null)
  100. {
  101. element.Text = e.NewValue as string;
  102. }
  103. }
  104. #endregion
  105.  
  106. #region PlaceholderProperty
  107. public string Placeholder { get
  108. {
  109. return (string)this.GetValue(PlaceholderProperty);
  110. }
  111. set
  112. {
  113. this.SetValue(PlaceholderProperty, value);
  114. }
  115. }
  116.  
  117. public static readonly DependencyProperty PlaceholderProperty =
  118. DependencyProperty.RegisterAttached("Placeholder", typeof(string), typeof(LabelRenderTextBox), new PropertyMetadata("", OnPlaceholderChanged));
  119.  
  120. private static void OnPlaceholderChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  121. {
  122. var element = obj as LabelRenderTextBox;
  123. if (element != null)
  124. {
  125. element.Placeholder = e.NewValue as string;
  126. }
  127. }
  128. #endregion
  129.  
  130. #region RequiredValueProperty
  131. public RequiredValues RequiredValue
  132. {
  133. get { return (RequiredValues)this.GetValue(RequiredValueProperty); }
  134. set
  135. {
  136. this.SetValue(RequiredValueProperty, value);
  137. }
  138. }
  139.  
  140. public static readonly DependencyProperty RequiredValueProperty =
  141. DependencyProperty.RegisterAttached("RequiredValue", typeof(RequiredValues), typeof(LabelRenderTextBox), new PropertyMetadata(RequiredValues.String, OnRequiredValueChanged));
  142.  
  143. private static void OnRequiredValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  144. {
  145. var element = obj as LabelRenderTextBox;
  146. if (element != null)
  147. {
  148. element.RequiredValue = (RequiredValues)e.NewValue;
  149. }
  150. }
  151. #endregion
  152.  
  153. #region UseSearchProperty
  154. public bool UseSearch
  155. {
  156. get { return (bool)this.GetValue(UseSearchProperty); }
  157. set
  158. {
  159. this.SetValue(UseSearchProperty, value);
  160. if (value)
  161. this.textbox.Style = this.FindResource("mySearchTextBoxStyle") as Style;
  162.  
  163. }
  164. }
  165.  
  166. public static readonly DependencyProperty UseSearchProperty =
  167. DependencyProperty.RegisterAttached("UseSearch", typeof(bool), typeof(LabelRenderTextBox), new PropertyMetadata(false, OnUseSearchChanged));
  168.  
  169. private static void OnUseSearchChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  170. {
  171. var element = obj as LabelRenderTextBox;
  172. if (element != null)
  173. {
  174. element.UseSearch = (bool)e.NewValue;
  175. }
  176. }
  177. #endregion
  178.  
  179. #region CaretIndexProperty
  180. public int CaretIndex {
  181. get { return (int)this.GetValue(CaretIndexProperty); }
  182. set
  183. {
  184. this.SetValue(CaretIndexProperty, value);
  185. this.textbox.CaretIndex = value;
  186. }
  187. }
  188.  
  189. public static readonly DependencyProperty CaretIndexProperty =
  190. DependencyProperty.RegisterAttached("CaretIndex", typeof(int), typeof(LabelRenderTextBox), new PropertyMetadata(0, OnCaretIndexChanged));
  191.  
  192. private static void OnCaretIndexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  193. {
  194. var element = obj as LabelRenderTextBox;
  195. if (element != null)
  196. {
  197. element.CaretIndex = (int)e.NewValue;
  198. }
  199. }
  200. #endregion
  201.  
  202. #region SelectionStartProperty
  203. public int SelectionStart
  204. {
  205. get { return (int)this.GetValue(SelectionStartProperty); }
  206. set
  207. {
  208. this.SetValue(SelectionStartProperty, value);
  209. this.textbox.SelectionStart = value;
  210. }
  211. }
  212.  
  213. public static readonly DependencyProperty SelectionStartProperty =
  214. DependencyProperty.RegisterAttached("SelectionStart", typeof(int), typeof(LabelRenderTextBox), new PropertyMetadata(0, OnSelectionStartChanged));
  215.  
  216. private static void OnSelectionStartChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  217. {
  218. var element = obj as LabelRenderTextBox;
  219. if (element != null)
  220. {
  221. element.SelectionStart = (int)e.NewValue;
  222. }
  223. }
  224. #endregion
  225.  
  226. #region EditModeProperty
  227. public EditModes EditMode {
  228. get { return (EditModes)this.GetValue(EditModeProperty); }
  229. set {
  230. this.SetValue(EditModeProperty, value);
  231. if (value == EditModes.Editable)
  232. {
  233. SetEditable(true);
  234. }
  235. else
  236. {
  237. SetEditable(false);
  238. }
  239. }
  240. }
  241.  
  242. public static readonly DependencyProperty EditModeProperty =
  243. DependencyProperty.RegisterAttached("EditMode", typeof(EditModes), typeof(LabelRenderTextBox), new PropertyMetadata(EditModes.Editable, OnEditModeChanged));
  244.  
  245. private static void OnEditModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  246. {
  247. var element = obj as LabelRenderTextBox;
  248. if (element != null)
  249. {
  250. element.EditMode = (EditModes)e.NewValue;
  251. }
  252. }
  253. #endregion
  254.  
  255. private void SetEditable(bool editable)
  256. {
  257. if (editable)
  258. {
  259. this.label.Visibility = Visibility.Collapsed;
  260. this.textbox.Visibility = Visibility.Visible;
  261. }
  262. else
  263. {
  264. this.label.Visibility = Visibility.Visible;
  265. this.textbox.Visibility = Visibility.Collapsed;
  266. }
  267. }
  268.  
  269. }
  270.  
  271. public enum EditModes
  272. {
  273. //编辑模式
  274. Editable = 0,
  275. //只读模式
  276. ReadOnly = 1,
  277. //只读模式展示,单击进入编辑模式,失去焦点后恢复只读模式
  278. Click = 2,
  279. //只读模式展示,双击进入编辑模式,失去焦点后恢复只读模式
  280. DoubleCLick = 3
  281. }
  282.  
  283. public enum RequiredValues
  284. {
  285. String = 0,
  286. Number = 1
  287. }
  288. }

C#

  

工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox的更多相关文章

  1. [WPF 自定义控件]开始一个自定义控件库项目

    1. 目标 我实现了一个自定义控件库,并且打算用这个控件库作例子写一些博客.这个控件库主要目标是用于教学,希望通过这些博客初学者可以学会为自己或公司创建自定义控件,并且对WPF有更深入的了解. 控件库 ...

  2. [WPF 自定义控件]自定义一个“传统”的 Validation.ErrorTemplate

    1. 什么是Validaion.ErrorTemplate 数据绑定模型允许您将与您Binding的对象相关联ValidationRules. 如果用户输入的值无效,你可能希望在应用程序 用户界面 ( ...

  3. ES 记录之如何创建一个索引映射,以及一些设置

    ElasticSearch 系列文章 1 ES 入门之一 安装ElasticSearcha 2 ES 记录之如何创建一个索引映射 3 ElasticSearch 学习记录之Text keyword 两 ...

  4. WPF自定义控件(一)の控件分类

    一.什么是控件(Controls) 控件是指对数据和方法的封装.控件可以有自己的属性和方法,其中属性是控件数据的简单访问者,方法则是控件的一些简单而可见的功能.控件创建过程包括设计.开发.调试(就是所 ...

  5. WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

    一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...

  6. WPF自定义控件与样式(1)-矢量字体图标(iconfont)

    一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...

  7. WPF自定义控件与样式(2)-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...

  8. WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享

    系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...

  9. WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Che ...

随机推荐

  1. Development 编程规范

    { 命名规范类命名 1)所有的类名,接口名(Protocol)均以大写字母开头,多单词组合时,后面的单词首字母大写.   类,接口名必须是有意义的,切忌使用中文拼音命名.另外所有类都要加标致前缀:“O ...

  2. Ruby 中文编码

    Ruby 中文编码 前面章节中我们已经学会了如何用 Ruby 输出 "Hello, World!",英文没有问题,但是如果你输出中文字符"你好,世界"就有可能会 ...

  3. 良田高拍仪集成vue项目

    一.硬件及开发包说明: 产品型号为良田高拍仪S1800A3,集成b/s系统,适用现代浏览器,图片使用BASE64数据.开发包的bin文件下的video.flt文件需要和高拍仪型号的硬件id对应,这个可 ...

  4. 20140415 HOG 不同继承方式的访问特性 虚函数工作原理

    1.HOG block重叠的好处 由于行人通常其形状可以视为柔体,人 的边缘位置不固定,而有一些移动,block 重叠后,一个边缘的梯度信息在两个相邻重叠的 block 中都能有所表达,这样即使边缘的 ...

  5. spark集群进入 bin 下面目录./spark-shell 出现Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

    spark集群启动的时候可以正常,进入 ./spark-shell 就会出现如下错误 配置文件:spark-env.sh export JAVA_HOME=/usr/java/jdk1.7.0_51e ...

  6. React:styled-components

    ``是es6的Template Literals(模版字符串),许多人对这个一知半解,今天在这边总结下: `${expression}`(表达式插补) var x; var y; sth.innerH ...

  7. 2018湘潭大学程序设计竞赛【H】

    题目链接:https://www.nowcoder.com/acm/contest/105/H 题意:两个操作,一个在[l,r]区间放颜色为c的球,一个统计在[l,r]里有多少不同颜色的球. 题解:哎 ...

  8. 控制音量大小widget

    由于手机音量按键非常悲剧的掉了.无法控制手机音量大小.使用起来非常不方便.所以决定写一个小widget放在桌面能够随时控制音量吧.也算是解决一点便利问题. 1.一个简单的widget 由于我的需求非常 ...

  9. JDBC_事务说明

    JDBC控制事务:1.事务:一个包含多个步骤的业务操作,如果这个业务操作被事务管理则多个步骤同时成功或同时失败2.操作: 1.开启事务 2.提交事务 3.回滚事务3.使用Connection对象来管理 ...

  10. jsonArray转换成List

    从字符串String转换成List 字符串格式: String jsonstr = "{'studentsjson':[{'student':'张三'},{'student':'李四'}] ...