系列文章目录 

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

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

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

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

WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式

WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox

WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu

WPF自定义控件与样式(10)-进度控件ProcessBar自定义样

WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox

WPF自定义控件与样式(14)-轻量MVVM模式实践

WPF自定义控件与样式(15)-终结篇

源代码下载地址:http://files.cnblogs.com/files/anding/Util.Controls.zip

Github项目地址https://github.com/kwonganding/wpf.controls

一.总结.声明

  关于本WPF,本人也只能算是一个刚入门的,在学习中和工作中,学习、借鉴了很多网友的文章和开源的项目的知识。发现提供实际项目开发需要的基础控件、样式的文章大都比较散,不成系列。因此基于现在项目中使用的基础UI库,写了这个系列,希望对有需要的人有所帮助。

  本系列包括本文共15篇,就到此为止了。关于一些问题再次说明一下:

  • 每一篇文章中都给出了基本所有主要代码,目的仅供参考学习,由于目前还是公司在使用中的项目,因此不便提供完整项目源码,有需要的同学还是多动动手吧!
  • 对于确实需要源码参考学的,推荐开源项目MahApps.Metro(http://mahapps.com/),我在那里面学习借鉴了很多,本系列中不少样式中都有她(就是她)的影子。
  • 本文会把一些额外遗漏的资源或代码一并提供出来

二.附录.本系列补充资源

2.1附加属性

  很多样式中使用了附加属性来对基础控件扩展,ControlAttachProperty.cs所有代码:

  1. /// <summary>
  2. /// 公共附加属性
  3. /// </summary>
  4. public static class ControlAttachProperty
  5. {
  6. /************************************ Attach Property **************************************/
  7.  
  8. #region FocusBackground 获得焦点背景色,
  9.  
  10. public static readonly DependencyProperty FocusBackgroundProperty = DependencyProperty.RegisterAttached(
  11. "FocusBackground", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
  12.  
  13. public static void SetFocusBackground(DependencyObject element, Brush value)
  14. {
  15. element.SetValue(FocusBackgroundProperty, value);
  16. }
  17.  
  18. public static Brush GetFocusBackground(DependencyObject element)
  19. {
  20. return (Brush)element.GetValue(FocusBackgroundProperty);
  21. }
  22.  
  23. #endregion
  24.  
  25. #region FocusForeground 获得焦点前景色,
  26.  
  27. public static readonly DependencyProperty FocusForegroundProperty = DependencyProperty.RegisterAttached(
  28. "FocusForeground", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
  29.  
  30. public static void SetFocusForeground(DependencyObject element, Brush value)
  31. {
  32. element.SetValue(FocusForegroundProperty, value);
  33. }
  34.  
  35. public static Brush GetFocusForeground(DependencyObject element)
  36. {
  37. return (Brush)element.GetValue(FocusForegroundProperty);
  38. }
  39.  
  40. #endregion
  41.  
  42. #region MouseOverBackgroundProperty 鼠标悬浮背景色
  43.  
  44. public static readonly DependencyProperty MouseOverBackgroundProperty = DependencyProperty.RegisterAttached(
  45. "MouseOverBackground", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
  46.  
  47. public static void SetMouseOverBackground(DependencyObject element, Brush value)
  48. {
  49. element.SetValue(MouseOverBackgroundProperty, value);
  50. }
  51.  
  52. public static Brush MouseOverBackground(DependencyObject element)
  53. {
  54. return (Brush)element.GetValue(FocusBackgroundProperty);
  55. }
  56.  
  57. #endregion
  58.  
  59. #region MouseOverForegroundProperty 鼠标悬浮前景色
  60.  
  61. public static readonly DependencyProperty MouseOverForegroundProperty = DependencyProperty.RegisterAttached(
  62. "MouseOverForeground", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
  63.  
  64. public static void SetMouseOverForeground(DependencyObject element, Brush value)
  65. {
  66. element.SetValue(MouseOverForegroundProperty, value);
  67. }
  68.  
  69. public static Brush MouseOverForeground(DependencyObject element)
  70. {
  71. return (Brush)element.GetValue(FocusForegroundProperty);
  72. }
  73.  
  74. #endregion
  75.  
  76. #region FocusBorderBrush 焦点边框色,输入控件
  77.  
  78. public static readonly DependencyProperty FocusBorderBrushProperty = DependencyProperty.RegisterAttached(
  79. "FocusBorderBrush", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
  80. public static void SetFocusBorderBrush(DependencyObject element, Brush value)
  81. {
  82. element.SetValue(FocusBorderBrushProperty, value);
  83. }
  84. public static Brush GetFocusBorderBrush(DependencyObject element)
  85. {
  86. return (Brush)element.GetValue(FocusBorderBrushProperty);
  87. }
  88.  
  89. #endregion
  90.  
  91. #region MouseOverBorderBrush 鼠标进入边框色,输入控件
  92.  
  93. public static readonly DependencyProperty MouseOverBorderBrushProperty =
  94. DependencyProperty.RegisterAttached("MouseOverBorderBrush", typeof(Brush), typeof(ControlAttachProperty),
  95. new FrameworkPropertyMetadata(Brushes.Transparent,
  96. FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.Inherits));
  97.  
  98. /// <summary>
  99. /// Sets the brush used to draw the mouse over brush.
  100. /// </summary>
  101. public static void SetMouseOverBorderBrush(DependencyObject obj, Brush value)
  102. {
  103. obj.SetValue(MouseOverBorderBrushProperty, value);
  104. }
  105.  
  106. /// <summary>
  107. /// Gets the brush used to draw the mouse over brush.
  108. /// </summary>
  109. [AttachedPropertyBrowsableForType(typeof(TextBox))]
  110. [AttachedPropertyBrowsableForType(typeof(CheckBox))]
  111. [AttachedPropertyBrowsableForType(typeof(RadioButton))]
  112. [AttachedPropertyBrowsableForType(typeof(DatePicker))]
  113. [AttachedPropertyBrowsableForType(typeof(ComboBox))]
  114. [AttachedPropertyBrowsableForType(typeof(RichTextBox))]
  115. public static Brush GetMouseOverBorderBrush(DependencyObject obj)
  116. {
  117. return (Brush)obj.GetValue(MouseOverBorderBrushProperty);
  118. }
  119.  
  120. #endregion
  121.  
  122. #region AttachContentProperty 附加组件模板
  123. /// <summary>
  124. /// 附加组件模板
  125. /// </summary>
  126. public static readonly DependencyProperty AttachContentProperty = DependencyProperty.RegisterAttached(
  127. "AttachContent", typeof(ControlTemplate), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
  128.  
  129. public static ControlTemplate GetAttachContent(DependencyObject d)
  130. {
  131. return (ControlTemplate)d.GetValue(AttachContentProperty);
  132. }
  133.  
  134. public static void SetAttachContent(DependencyObject obj, ControlTemplate value)
  135. {
  136. obj.SetValue(AttachContentProperty, value);
  137. }
  138. #endregion
  139.  
  140. #region WatermarkProperty 水印
  141. /// <summary>
  142. /// 水印
  143. /// </summary>
  144. public static readonly DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached(
  145. "Watermark", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(""));
  146.  
  147. public static string GetWatermark(DependencyObject d)
  148. {
  149. return (string)d.GetValue(WatermarkProperty);
  150. }
  151.  
  152. public static void SetWatermark(DependencyObject obj, string value)
  153. {
  154. obj.SetValue(WatermarkProperty, value);
  155. }
  156. #endregion
  157.  
  158. #region FIconProperty 字体图标
  159. /// <summary>
  160. /// 字体图标
  161. /// </summary>
  162. public static readonly DependencyProperty FIconProperty = DependencyProperty.RegisterAttached(
  163. "FIcon", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(""));
  164.  
  165. public static string GetFIcon(DependencyObject d)
  166. {
  167. return (string)d.GetValue(FIconProperty);
  168. }
  169.  
  170. public static void SetFIcon(DependencyObject obj, string value)
  171. {
  172. obj.SetValue(FIconProperty, value);
  173. }
  174. #endregion
  175.  
  176. #region FIconSizeProperty 字体图标大小
  177. /// <summary>
  178. /// 字体图标
  179. /// </summary>
  180. public static readonly DependencyProperty FIconSizeProperty = DependencyProperty.RegisterAttached(
  181. "FIconSize", typeof(double), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(12D));
  182.  
  183. public static double GetFIconSize(DependencyObject d)
  184. {
  185. return (double)d.GetValue(FIconSizeProperty);
  186. }
  187.  
  188. public static void SetFIconSize(DependencyObject obj, double value)
  189. {
  190. obj.SetValue(FIconSizeProperty, value);
  191. }
  192. #endregion
  193.  
  194. #region FIconMarginProperty 字体图标边距
  195. /// <summary>
  196. /// 字体图标
  197. /// </summary>
  198. public static readonly DependencyProperty FIconMarginProperty = DependencyProperty.RegisterAttached(
  199. "FIconMargin", typeof(Thickness), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
  200.  
  201. public static Thickness GetFIconMargin(DependencyObject d)
  202. {
  203. return (Thickness)d.GetValue(FIconMarginProperty);
  204. }
  205.  
  206. public static void SetFIconMargin(DependencyObject obj, Thickness value)
  207. {
  208. obj.SetValue(FIconMarginProperty, value);
  209. }
  210. #endregion
  211.  
  212. #region AllowsAnimationProperty 启用旋转动画
  213. /// <summary>
  214. /// 启用旋转动画
  215. /// </summary>
  216. public static readonly DependencyProperty AllowsAnimationProperty = DependencyProperty.RegisterAttached("AllowsAnimation"
  217. , typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, AllowsAnimationChanged));
  218.  
  219. public static bool GetAllowsAnimation(DependencyObject d)
  220. {
  221. return (bool)d.GetValue(AllowsAnimationProperty);
  222. }
  223.  
  224. public static void SetAllowsAnimation(DependencyObject obj, bool value)
  225. {
  226. obj.SetValue(AllowsAnimationProperty, value);
  227. }
  228.  
  229. /// <summary>
  230. /// 旋转动画刻度
  231. /// </summary>
  232. private static DoubleAnimation RotateAnimation = new DoubleAnimation(, new Duration(TimeSpan.FromMilliseconds()));
  233.  
  234. /// <summary>
  235. /// 绑定动画事件
  236. /// </summary>
  237. private static void AllowsAnimationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  238. {
  239. var uc = d as FrameworkElement;
  240. if (uc == null) return;
  241. if (uc.RenderTransformOrigin == new Point(, ))
  242. {
  243. uc.RenderTransformOrigin = new Point(0.5, 0.5);
  244. RotateTransform trans = new RotateTransform();
  245. uc.RenderTransform = trans;
  246. }
  247. var value = (bool)e.NewValue;
  248. if (value)
  249. {
  250. RotateAnimation.To = ;
  251. uc.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, RotateAnimation);
  252. }
  253. else
  254. {
  255. RotateAnimation.To = ;
  256. uc.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, RotateAnimation);
  257. }
  258. }
  259. #endregion
  260.  
  261. #region CornerRadiusProperty Border圆角
  262. /// <summary>
  263. /// Border圆角
  264. /// </summary>
  265. public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.RegisterAttached(
  266. "CornerRadius", typeof(CornerRadius), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
  267.  
  268. public static CornerRadius GetCornerRadius(DependencyObject d)
  269. {
  270. return (CornerRadius)d.GetValue(CornerRadiusProperty);
  271. }
  272.  
  273. public static void SetCornerRadius(DependencyObject obj, CornerRadius value)
  274. {
  275. obj.SetValue(CornerRadiusProperty, value);
  276. }
  277. #endregion
  278.  
  279. #region LabelProperty TextBox的头部Label
  280. /// <summary>
  281. /// TextBox的头部Label
  282. /// </summary>
  283. public static readonly DependencyProperty LabelProperty = DependencyProperty.RegisterAttached(
  284. "Label", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
  285.  
  286. [AttachedPropertyBrowsableForType(typeof(TextBox))]
  287. public static string GetLabel(DependencyObject d)
  288. {
  289. return (string)d.GetValue(LabelProperty);
  290. }
  291.  
  292. public static void SetLabel(DependencyObject obj, string value)
  293. {
  294. obj.SetValue(LabelProperty, value);
  295. }
  296. #endregion
  297.  
  298. #region LabelTemplateProperty TextBox的头部Label模板
  299. /// <summary>
  300. /// TextBox的头部Label模板
  301. /// </summary>
  302. public static readonly DependencyProperty LabelTemplateProperty = DependencyProperty.RegisterAttached(
  303. "LabelTemplate", typeof(ControlTemplate), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
  304.  
  305. [AttachedPropertyBrowsableForType(typeof(TextBox))]
  306. public static ControlTemplate GetLabelTemplate(DependencyObject d)
  307. {
  308. return (ControlTemplate)d.GetValue(LabelTemplateProperty);
  309. }
  310.  
  311. public static void SetLabelTemplate(DependencyObject obj, ControlTemplate value)
  312. {
  313. obj.SetValue(LabelTemplateProperty, value);
  314. }
  315. #endregion
  316.  
  317. /************************************ RoutedUICommand Behavior enable **************************************/
  318.  
  319. #region IsClearTextButtonBehaviorEnabledProperty 清除输入框Text值按钮行为开关(设为ture时才会绑定事件)
  320. /// <summary>
  321. /// 清除输入框Text值按钮行为开关
  322. /// </summary>
  323. public static readonly DependencyProperty IsClearTextButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached("IsClearTextButtonBehaviorEnabled"
  324. , typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, IsClearTextButtonBehaviorEnabledChanged));
  325.  
  326. [AttachedPropertyBrowsableForType(typeof(TextBox))]
  327. public static bool GetIsClearTextButtonBehaviorEnabled(DependencyObject d)
  328. {
  329. return (bool)d.GetValue(IsClearTextButtonBehaviorEnabledProperty);
  330. }
  331.  
  332. public static void SetIsClearTextButtonBehaviorEnabled(DependencyObject obj, bool value)
  333. {
  334. obj.SetValue(IsClearTextButtonBehaviorEnabledProperty, value);
  335. }
  336.  
  337. /// <summary>
  338. /// 绑定清除Text操作的按钮事件
  339. /// </summary>
  340. private static void IsClearTextButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  341. {
  342. var button = d as FButton;
  343. if (e.OldValue != e.NewValue && button != null)
  344. {
  345. button.CommandBindings.Add(ClearTextCommandBinding);
  346. }
  347. }
  348.  
  349. #endregion
  350.  
  351. #region IsOpenFileButtonBehaviorEnabledProperty 选择文件命令行为开关
  352. /// <summary>
  353. /// 选择文件命令行为开关
  354. /// </summary>
  355. public static readonly DependencyProperty IsOpenFileButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached("IsOpenFileButtonBehaviorEnabled"
  356. , typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, IsOpenFileButtonBehaviorEnabledChanged));
  357.  
  358. [AttachedPropertyBrowsableForType(typeof(TextBox))]
  359. public static bool GetIsOpenFileButtonBehaviorEnabled(DependencyObject d)
  360. {
  361. return (bool)d.GetValue(IsOpenFileButtonBehaviorEnabledProperty);
  362. }
  363.  
  364. public static void SetIsOpenFileButtonBehaviorEnabled(DependencyObject obj, bool value)
  365. {
  366. obj.SetValue(IsOpenFileButtonBehaviorEnabledProperty, value);
  367. }
  368.  
  369. private static void IsOpenFileButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  370. {
  371. var button = d as FButton;
  372. if (e.OldValue != e.NewValue && button != null)
  373. {
  374. button.CommandBindings.Add(OpenFileCommandBinding);
  375. }
  376. }
  377.  
  378. #endregion
  379.  
  380. #region IsOpenFolderButtonBehaviorEnabledProperty 选择文件夹命令行为开关
  381. /// <summary>
  382. /// 选择文件夹命令行为开关
  383. /// </summary>
  384. public static readonly DependencyProperty IsOpenFolderButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached("IsOpenFolderButtonBehaviorEnabled"
  385. , typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, IsOpenFolderButtonBehaviorEnabledChanged));
  386.  
  387. [AttachedPropertyBrowsableForType(typeof(TextBox))]
  388. public static bool GetIsOpenFolderButtonBehaviorEnabled(DependencyObject d)
  389. {
  390. return (bool)d.GetValue(IsOpenFolderButtonBehaviorEnabledProperty);
  391. }
  392.  
  393. public static void SetIsOpenFolderButtonBehaviorEnabled(DependencyObject obj, bool value)
  394. {
  395. obj.SetValue(IsOpenFolderButtonBehaviorEnabledProperty, value);
  396. }
  397.  
  398. private static void IsOpenFolderButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  399. {
  400. var button = d as FButton;
  401. if (e.OldValue != e.NewValue && button != null)
  402. {
  403. button.CommandBindings.Add(OpenFolderCommandBinding);
  404. }
  405. }
  406.  
  407. #endregion
  408.  
  409. #region IsSaveFileButtonBehaviorEnabledProperty 选择文件保存路径及名称
  410. /// <summary>
  411. /// 选择文件保存路径及名称
  412. /// </summary>
  413. public static readonly DependencyProperty IsSaveFileButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached("IsSaveFileButtonBehaviorEnabled"
  414. , typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, IsSaveFileButtonBehaviorEnabledChanged));
  415.  
  416. [AttachedPropertyBrowsableForType(typeof(TextBox))]
  417. public static bool GetIsSaveFileButtonBehaviorEnabled(DependencyObject d)
  418. {
  419. return (bool)d.GetValue(IsSaveFileButtonBehaviorEnabledProperty);
  420. }
  421.  
  422. public static void SetIsSaveFileButtonBehaviorEnabled(DependencyObject obj, bool value)
  423. {
  424. obj.SetValue(IsSaveFileButtonBehaviorEnabledProperty, value);
  425. }
  426.  
  427. private static void IsSaveFileButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  428. {
  429. var button = d as FButton;
  430. if (e.OldValue != e.NewValue && button != null)
  431. {
  432. button.CommandBindings.Add(SaveFileCommandBinding);
  433. }
  434. }
  435.  
  436. #endregion
  437.  
  438. /************************************ RoutedUICommand **************************************/
  439.  
  440. #region ClearTextCommand 清除输入框Text事件命令
  441.  
  442. /// <summary>
  443. /// 清除输入框Text事件命令,需要使用IsClearTextButtonBehaviorEnabledChanged绑定命令
  444. /// </summary>
  445. public static RoutedUICommand ClearTextCommand { get; private set; }
  446.  
  447. /// <summary>
  448. /// ClearTextCommand绑定事件
  449. /// </summary>
  450. private static readonly CommandBinding ClearTextCommandBinding;
  451.  
  452. /// <summary>
  453. /// 清除输入框文本值
  454. /// </summary>
  455. private static void ClearButtonClick(object sender, ExecutedRoutedEventArgs e)
  456. {
  457. var tbox = e.Parameter as FrameworkElement;
  458. if (tbox == null) return;
  459. if (tbox is TextBox)
  460. {
  461. ((TextBox)tbox).Clear();
  462. }
  463. if (tbox is PasswordBox)
  464. {
  465. ((PasswordBox)tbox).Clear();
  466. }
  467. if (tbox is ComboBox)
  468. {
  469. var cb = tbox as ComboBox;
  470. cb.SelectedItem = null;
  471. cb.Text = string.Empty;
  472. }
  473. if (tbox is MultiComboBox)
  474. {
  475. var cb = tbox as MultiComboBox;
  476. cb.SelectedItem = null;
  477. cb.UnselectAll();
  478. cb.Text = string.Empty;
  479. }
  480. if (tbox is DatePicker)
  481. {
  482. var dp = tbox as DatePicker;
  483. dp.SelectedDate = null;
  484. dp.Text = string.Empty;
  485. }
  486. tbox.Focus();
  487. }
  488.  
  489. #endregion
  490.  
  491. #region OpenFileCommand 选择文件命令
  492.  
  493. /// <summary>
  494. /// 选择文件命令,需要使用IsClearTextButtonBehaviorEnabledChanged绑定命令
  495. /// </summary>
  496. public static RoutedUICommand OpenFileCommand { get; private set; }
  497.  
  498. /// <summary>
  499. /// OpenFileCommand绑定事件
  500. /// </summary>
  501. private static readonly CommandBinding OpenFileCommandBinding;
  502.  
  503. /// <summary>
  504. /// 执行OpenFileCommand
  505. /// </summary>
  506. private static void OpenFileButtonClick(object sender, ExecutedRoutedEventArgs e)
  507. {
  508. var tbox = e.Parameter as FrameworkElement;
  509. var txt = tbox as TextBox;
  510. string filter = txt.Tag == null ? "所有文件(*.*)|*.*" : txt.Tag.ToString();
  511. if (filter.Contains(".bin"))
  512. {
  513. filter += "|所有文件(*.*)|*.*";
  514. }
  515. if (txt == null) return;
  516. OpenFileDialog fd = new OpenFileDialog();
  517. fd.Title = "请选择文件";
  518. //“图像文件(*.bmp, *.jpg)|*.bmp;*.jpg|所有文件(*.*)|*.*”
  519. fd.Filter = filter;
  520. fd.FileName = txt.Text.Trim();
  521. if (fd.ShowDialog() == true)
  522. {
  523. txt.Text = fd.FileName;
  524. }
  525. tbox.Focus();
  526. }
  527.  
  528. #endregion
  529.  
  530. #region OpenFolderCommand 选择文件夹命令
  531.  
  532. /// <summary>
  533. /// 选择文件夹命令
  534. /// </summary>
  535. public static RoutedUICommand OpenFolderCommand { get; private set; }
  536.  
  537. /// <summary>
  538. /// OpenFolderCommand绑定事件
  539. /// </summary>
  540. private static readonly CommandBinding OpenFolderCommandBinding;
  541.  
  542. /// <summary>
  543. /// 执行OpenFolderCommand
  544. /// </summary>
  545. private static void OpenFolderButtonClick(object sender, ExecutedRoutedEventArgs e)
  546. {
  547. var tbox = e.Parameter as FrameworkElement;
  548. var txt = tbox as TextBox;
  549. if (txt == null) return;
  550. FolderBrowserDialog fd = new FolderBrowserDialog();
  551. fd.Description = "请选择文件路径";
  552. fd.SelectedPath = txt.Text.Trim();
  553. if (fd.ShowDialog() == DialogResult.OK)
  554. {
  555. txt.Text = fd.SelectedPath;
  556. }
  557. tbox.Focus();
  558. }
  559.  
  560. #endregion
  561.  
  562. #region SaveFileCommand 选择文件保存路径及名称
  563.  
  564. /// <summary>
  565. /// 选择文件保存路径及名称
  566. /// </summary>
  567. public static RoutedUICommand SaveFileCommand { get; private set; }
  568.  
  569. /// <summary>
  570. /// SaveFileCommand绑定事件
  571. /// </summary>
  572. private static readonly CommandBinding SaveFileCommandBinding;
  573.  
  574. /// <summary>
  575. /// 执行OpenFileCommand
  576. /// </summary>
  577. private static void SaveFileButtonClick(object sender, ExecutedRoutedEventArgs e)
  578. {
  579. var tbox = e.Parameter as FrameworkElement;
  580. var txt = tbox as TextBox;
  581. if (txt == null) return;
  582. SaveFileDialog fd = new SaveFileDialog();
  583. fd.Title = "文件保存路径";
  584. fd.Filter = "所有文件(*.*)|*.*";
  585. fd.FileName = txt.Text.Trim();
  586. if (fd.ShowDialog() == DialogResult.OK)
  587. {
  588. txt.Text = fd.FileName;
  589. }
  590. tbox.Focus();
  591. }
  592.  
  593. #endregion
  594.  
  595. /// <summary>
  596. /// 静态构造函数
  597. /// </summary>
  598. static ControlAttachProperty()
  599. {
  600. //ClearTextCommand
  601. ClearTextCommand = new RoutedUICommand();
  602. ClearTextCommandBinding = new CommandBinding(ClearTextCommand);
  603. ClearTextCommandBinding.Executed += ClearButtonClick;
  604. //OpenFileCommand
  605. OpenFileCommand = new RoutedUICommand();
  606. OpenFileCommandBinding = new CommandBinding(OpenFileCommand);
  607. OpenFileCommandBinding.Executed += OpenFileButtonClick;
  608. //OpenFolderCommand
  609. OpenFolderCommand = new RoutedUICommand();
  610. OpenFolderCommandBinding = new CommandBinding(OpenFolderCommand);
  611. OpenFolderCommandBinding.Executed += OpenFolderButtonClick;
  612.  
  613. SaveFileCommand = new RoutedUICommand();
  614. SaveFileCommandBinding = new CommandBinding(SaveFileCommand);
  615. SaveFileCommandBinding.Executed += SaveFileButtonClick;
  616. }
  617. }

  其中有一个比较好玩的附加属性就是AllowsAnimationProperty,实现旋转动画的支持,类型为bool,可以有很多种使用方式,如绑定到普通控件的IsMouseOver上,当鼠标悬浮就旋转180度,移开又转回去,效果(gif录制的问题,看上去没有那么流程):

  也可以绑定到CheckBox、RadioButton、ToggleButton的IsChecked属性上。

  1. <TextBlock Text="" Style="{StaticResource FIcon}" Margin="3" FontSize="40"
  2. core:ControlAttachProperty.AllowsAnimation="{Binding IsMouseOver,RelativeSource={RelativeSource Self}}"></TextBlock>
  3. <core:FImage Margin="3" Width="30" Height="30" Source="Images/qq.png"
    core:ControlAttachProperty.AllowsAnimation="{Binding IsMouseOver,RelativeSource={RelativeSource Self}}"></core:FImage>

2.2扩展方法

  静态扩展类ControlExtession.cs代码:

  1. public static class ControlExtession
  2. {
  3. #region BindCommand
  4.  
  5. /// <summary>
  6. /// 绑定命令和命令事件到宿主UI
  7. /// </summary>
  8. public static void BindCommand(this UIElement @ui, ICommand com, Action<object, ExecutedRoutedEventArgs> call)
  9. {
  10. var bind = new CommandBinding(com);
  11. bind.Executed += new ExecutedRoutedEventHandler(call);
  12. @ui.CommandBindings.Add(bind);
  13. }
  14.  
  15. /// <summary>
  16. /// 绑定RelayCommand命令到宿主UI
  17. /// </summary>
  18. public static void BindCommand(this UIElement @ui, RelayCommand<object> com)
  19. {
  20. var bind = new CommandBinding(com);
  21. bind.Executed += delegate(object sender, ExecutedRoutedEventArgs e)
  22. {
  23. com.ExecuteCommand(e.Parameter);
  24. };
  25. @ui.CommandBindings.Add(bind);
  26. }
  27.  
  28. #endregion
  29.  
  30. #region TreeView操作扩展方法
  31. //code:http://www.codeproject.com/Articles/36193/WPF-TreeView-tools
  32.  
  33. /// <summary>
  34. /// Returns the TreeViewItem of a data bound object.
  35. /// </summary>
  36. /// <param name="treeView">TreeView</param>
  37. /// <param name="obj">Data bound object</param>
  38. /// <returns>The TreeViewItem of the data bound object or null.</returns>
  39. public static TreeViewItem GetItemFromObject(this TreeView treeView, object obj)
  40. {
  41. try
  42. {
  43. DependencyObject dObject = GetContainerFormObject(treeView, obj);
  44. TreeViewItem tvi = dObject as TreeViewItem;
  45. while (tvi == null)
  46. {
  47. dObject = VisualTreeHelper.GetParent(dObject);
  48. tvi = dObject as TreeViewItem;
  49. }
  50. return tvi;
  51. }
  52. catch
  53. {
  54. }
  55. return null;
  56. }
  57.  
  58. private static DependencyObject GetContainerFormObject(ItemsControl item, object obj)
  59. {
  60. if (item == null)
  61. return null;
  62.  
  63. DependencyObject dObject = null;
  64. dObject = item.ItemContainerGenerator.ContainerFromItem(obj);
  65.  
  66. if (dObject != null)
  67. return dObject;
  68.  
  69. var query = from childItem in item.Items.Cast<object>()
  70. let childControl = item.ItemContainerGenerator.ContainerFromItem(childItem) as ItemsControl
  71. select GetContainerFormObject(childControl, obj);
  72.  
  73. return query.FirstOrDefault(i => i != null);
  74. }
  75.  
  76. /// <summary>
  77. /// Selects a data bound object of a TreeView.
  78. /// </summary>
  79. /// <param name="treeView">TreeView</param>
  80. /// <param name="obj">Data bound object</param>
  81. public static void SelectObject(this TreeView treeView, object obj)
  82. {
  83. treeView.SelectObject(obj, true);
  84. }
  85.  
  86. /// <summary>
  87. /// Selects or deselects a data bound object of a TreeView.
  88. /// </summary>
  89. /// <param name="treeView">TreeView</param>
  90. /// <param name="obj">Data bound object</param>
  91. /// <param name="selected">select or deselect</param>
  92. public static void SelectObject(this TreeView treeView, object obj, bool selected)
  93. {
  94. var tvi = treeView.GetItemFromObject(obj);
  95. if (tvi != null)
  96. {
  97. tvi.IsSelected = selected;
  98. }
  99. }
  100.  
  101. /// <summary>
  102. /// Returns if a data bound object of a TreeView is selected.
  103. /// </summary>
  104. /// <param name="treeView">TreeView</param>
  105. /// <param name="obj">Data bound object</param>
  106. /// <returns>Returns true if the object is selected, and false if it is not selected or obj is not in the tree.</returns>
  107. public static bool IsObjectSelected(this TreeView treeView, object obj)
  108. {
  109. var tvi = treeView.GetItemFromObject(obj);
  110. if (tvi != null)
  111. {
  112. return tvi.IsSelected;
  113. }
  114. return false;
  115. }
  116.  
  117. /// <summary>
  118. /// Returns if a data bound object of a TreeView is focused.
  119. /// </summary>
  120. /// <param name="treeView">TreeView</param>
  121. /// <param name="obj">Data bound object</param>
  122. /// <returns>Returns true if the object is focused, and false if it is not focused or obj is not in the tree.</returns>
  123. public static bool IsObjectFocused(this TreeView treeView, object obj)
  124. {
  125. var tvi = treeView.GetItemFromObject(obj);
  126. if (tvi != null)
  127. {
  128. return tvi.IsFocused;
  129. }
  130. return false;
  131. }
  132.  
  133. /// <summary>
  134. /// Expands a data bound object of a TreeView.
  135. /// </summary>
  136. /// <param name="treeView">TreeView</param>
  137. /// <param name="obj">Data bound object</param>
  138. public static void ExpandObject(this TreeView treeView, object obj)
  139. {
  140. treeView.ExpandObject(obj, true);
  141. }
  142.  
  143. /// <summary>
  144. /// Expands or collapses a data bound object of a TreeView.
  145. /// </summary>
  146. /// <param name="treeView">TreeView</param>
  147. /// <param name="obj">Data bound object</param>
  148. /// <param name="expanded">expand or collapse</param>
  149. public static void ExpandObject(this TreeView treeView, object obj, bool expanded)
  150. {
  151. var tvi = treeView.GetItemFromObject(obj);
  152. if (tvi != null)
  153. {
  154. tvi.IsExpanded = expanded;
  155. if (expanded)
  156. {
  157. // update layout, so that following calls to f.e. SelectObject on child nodes will
  158. // find theire TreeViewNodes
  159. treeView.UpdateLayout();
  160. }
  161. }
  162. }
  163.  
  164. /// <summary>
  165. /// Returns if a douta bound object of a TreeView is expanded.
  166. /// </summary>
  167. /// <param name="treeView">TreeView</param>
  168. /// <param name="obj">Data bound object</param>
  169. /// <returns>Returns true if the object is expanded, and false if it is collapsed or obj is not in the tree.</returns>
  170. public static bool IsObjectExpanded(this TreeView treeView, object obj)
  171. {
  172. var tvi = treeView.GetItemFromObject(obj);
  173. if (tvi != null)
  174. {
  175. return tvi.IsExpanded;
  176. }
  177. return false;
  178. }
  179.  
  180. /// <summary>
  181. /// Retuns the parent TreeViewItem.
  182. /// </summary>
  183. /// <param name="item">TreeViewItem</param>
  184. /// <returns>Parent TreeViewItem</returns>
  185. public static TreeViewItem GetParentItem(this TreeViewItem item)
  186. {
  187. var dObject = VisualTreeHelper.GetParent(item);
  188. TreeViewItem tvi = dObject as TreeViewItem;
  189. while (tvi == null)
  190. {
  191. dObject = VisualTreeHelper.GetParent(dObject);
  192. tvi = dObject as TreeViewItem;
  193. }
  194. return tvi;
  195. }
  196.  
  197. #endregion
  198.  
  199. }

2.3配色资源Colors.xaml

  本系列前面文章中,基本所有样式中都没有直接使用具体色彩,而是通过资源的方式配置的,这些配色资源都在Colors.xaml中。这样的设计理论上可以实现换肤,在不同客户端中也很容易定制自己需要的风格色彩搭配。 Colors.xaml代码:

  1. <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  2. xmlns:sys="clr-namespace:System;assembly=mscorlib"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  4.  
  5. <!--Window窗体-->
  6. <SolidColorBrush x:Key="WindowBackground" Color="#093B5D"></SolidColorBrush>
  7. <SolidColorBrush x:Key="WindowInnerBackground" Color="Transparent"></SolidColorBrush>
  8. <!--<ImageBrush x:Key="WindowInnerBackground" Stretch="Fill"
  9. ImageSource="pack://application:,,,/XLY.Framework.WPFTest;component/Images/back/b2.jpg" Opacity="1"
  10. Viewport="0,0,1,1" ViewportUnits="Absolute" TileMode="Tile" AlignmentX="Left" AlignmentY="Top"/>-->
  11.  
  12. <SolidColorBrush x:Key="WindowBorderBrush" Color="#920892"></SolidColorBrush>
  13. <DropShadowEffect x:Key="WindowDropShadow" Color="#F472F4" BlurRadius="8" ShadowDepth="0" Direction="0" Opacity="0.7" />
  14. <SolidColorBrush x:Key="CaptionForeground" Color="White"></SolidColorBrush>
  15. <!--<LinearGradientBrush x:Key="CaptionBackground" StartPoint="0.5,0" EndPoint="0.5,1">
  16. <GradientStop Color="#571457" Offset="0"/>
  17. <GradientStop Color="#6A196A" Offset="1"/>
  18. </LinearGradientBrush>-->
  19. <ImageBrush x:Key="CaptionBackground"
  20. ImageSource="pack://application:,,,/XLY.Framework.WPFTest;component/Images/back/b2.jpg" Opacity="1"
  21. Viewport="0,0,202,143" ViewportUnits="Absolute" TileMode="Tile" AlignmentX="Left" AlignmentY="Top"/>
  22.  
  23. <!--MessageBoxX-->
  24. <SolidColorBrush x:Key="InfoForeground" Color="White"></SolidColorBrush>
  25. <SolidColorBrush x:Key="QuestionForeground" Color="#74B80C"></SolidColorBrush>
  26. <SolidColorBrush x:Key="WarningForeground" Color="DarkOrange"></SolidColorBrush>
  27. <SolidColorBrush x:Key="ErrorForeground" Color="#E74E4E"></SolidColorBrush>
  28. <!--WaitingBox-->
  29. <SolidColorBrush x:Key="WaitingBoxBackground" Color="#921692"></SolidColorBrush>
  30. <!--边框:Menu-->
  31. <DropShadowEffect x:Key="DefaultDropShadow" Color="Black" BlurRadius="5" ShadowDepth="2" Direction="315" Opacity="0.6" />
  32. <!--输入组件-->
  33. <SolidColorBrush x:Key="TextForeground" Color="White"></SolidColorBrush>
  34. <SolidColorBrush x:Key="TextBackground" Color="#0D234B"></SolidColorBrush>
  35. <SolidColorBrush x:Key="TextSelectionBrush" Color="#8F8787"></SolidColorBrush>
  36. <!--TextBox默认Label颜色-->
  37. <SolidColorBrush x:Key="TextLabelBackground" Color="#508AB6"></SolidColorBrush>
  38. <!--输入框-->
  39. <SolidColorBrush x:Key="ControlBorderBrush" Color="#999C9F"></SolidColorBrush>
  40. <SolidColorBrush x:Key="MouseOverBorderBrush" Color="#F6D1D1"></SolidColorBrush>
  41. <SolidColorBrush x:Key="FocusBackground" Color="#365080"></SolidColorBrush>
  42. <SolidColorBrush x:Key="FocusBorderBrush" Color="#EBCECE"></SolidColorBrush>
  43. <!--ScrollBar-->
  44. <SolidColorBrush x:Key="ScrollBarForeround" Color="#877F7F"></SolidColorBrush>
  45. <SolidColorBrush x:Key="ScrollBarBackground" Color="#3E3E42"></SolidColorBrush>
  46.  
  47. <!--ItemsControl:DataGrid,Tree-->
  48. <sys:Double x:Key="HeaderFontSize">14</sys:Double>
  49. <SolidColorBrush x:Key="HeaderBorderBrush" Color="#A6FFA500"></SolidColorBrush>
  50. <SolidColorBrush x:Key="HeaderBackground" Color="#0A48D3"></SolidColorBrush>
  51. <SolidColorBrush x:Key="ItemsContentBackground" Color="#1389D7"></SolidColorBrush>
  52. <SolidColorBrush x:Key="ItemsAlternationContentBackground" Color="#128EE0"></SolidColorBrush>
  53. <SolidColorBrush x:Key="GridLinesBrush" Color="#A6D0C2A7"></SolidColorBrush>
  54. <SolidColorBrush x:Key="ItemSelectedForeground" Color="White"></SolidColorBrush>
  55. <SolidColorBrush x:Key="ItemSelectedBackground" Color="#A145F8"></SolidColorBrush>
  56. <SolidColorBrush x:Key="ItemMouseOverBackground" Color="#BA7DF4"></SolidColorBrush>
  57. <SolidColorBrush x:Key="ItemMouseOverForeground" Color="White"></SolidColorBrush>
  58. <!--高亮:日历Today-->
  59. <SolidColorBrush x:Key="ItemHighlighteBackground" Color="Blue"></SolidColorBrush>
  60. <SolidColorBrush x:Key="ItemHighlighteForeground" Color="White"></SolidColorBrush>
  61.  
  62. <!--普通无背景按钮-->
  63. <SolidColorBrush x:Key="CheckedForeground" Color="#F7B63E"></SolidColorBrush>
  64. <SolidColorBrush x:Key="MouseOverForeground" Color="Orange"></SolidColorBrush>
  65. <SolidColorBrush x:Key="PressedForeground" Color="DarkOrange"></SolidColorBrush>
  66. <SolidColorBrush x:Key="LinkForeground" Color="#0816BB"></SolidColorBrush>
  67. <!--Popup,ComboBox-->
  68. <SolidColorBrush x:Key="PopupBackground" Color="#066EB3"></SolidColorBrush>
  69. <!--Button-->
  70. <SolidColorBrush x:Key="ButtonBackground" Color="#1D4A9A"></SolidColorBrush>
  71. <SolidColorBrush x:Key="ButtonForeground" Color="White"></SolidColorBrush>
  72. <SolidColorBrush x:Key="ButtonMouseOverBackground" Color="Orange"></SolidColorBrush>
  73. <SolidColorBrush x:Key="ButtonMouseOverForeground" Color="White"></SolidColorBrush>
  74. <SolidColorBrush x:Key="ButtonPressedBackground" Color="DarkOrange"></SolidColorBrush>
  75. <SolidColorBrush x:Key="ButtonPressedForeground" Color="White"></SolidColorBrush>
  76. <!--Menu-->
  77. <SolidColorBrush x:Key="MenuForeground" Color="#920892"></SolidColorBrush>
  78. <SolidColorBrush x:Key="MenuBackground" Color="#DDD1D1"></SolidColorBrush>
  79. <SolidColorBrush x:Key="MenuBorderBrush" Color="DarkBlue"></SolidColorBrush>
  80. <SolidColorBrush x:Key="MenuMouseOverBackground" Color="#0D3CD2"></SolidColorBrush>
  81. <SolidColorBrush x:Key="MenuMouseOverForeground" Color="White"></SolidColorBrush>
  82. <SolidColorBrush x:Key="MenuPressedBackground" Color="#082CA0"></SolidColorBrush>
  83. <SolidColorBrush x:Key="MenuPressedForeground" Color="White"></SolidColorBrush>
  84. <!--State brush-->
  85. <SolidColorBrush x:Key="SuccessfulfaiBrush" Color="#16B32A"></SolidColorBrush>
  86. <SolidColorBrush x:Key="FailedBrush" Color="#B92222"></SolidColorBrush>
  87.  
  88. <FontFamily x:Key="FontFamily" >Microsoft YaHei</FontFamily>
  89. <sys:Double x:Key="FontSize">13</sys:Double>
  90. <sys:Double x:Key="DisableOpacity">0.5</sys:Double>
  91. <sys:Double x:Key="ReadonlyOpacity">0.88</sys:Double>
  92. <sys:Double x:Key="WatermarkOpacity">0.4</sys:Double>
  93. <sys:String x:Key="DateFormat">yyyy年MM月dd日</sys:String>
  94. <sys:String x:Key="DateTimeFormat">yyyy-MM-dd HH:mm:ss</sys:String>
  95.  
  96. </ResourceDictionary>

2.4转换器

  BackgroundToForegroundConverter.cs代码:

  1. /// <summary>
  2. /// 根据背景色获取前景色。当然也可反着用
  3. /// </summary>
  4. public class BackgroundToForegroundConverter : IValueConverter
  5. {
  6. private Color IdealTextColor(Color bg)
  7. {
  8. const int nThreshold = ;
  9. var bgDelta = System.Convert.ToInt32((bg.R * 0.299) + (bg.G * 0.587) + (bg.B * 0.114));
  10. var foreColor = ( - bgDelta < nThreshold) ? Colors.Black : Colors.White;
  11. return foreColor;
  12. }
  13.  
  14. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  15. {
  16. if (value is SolidColorBrush)
  17. {
  18. var idealForegroundColor = this.IdealTextColor(((SolidColorBrush)value).Color);
  19. var foreGroundBrush = new SolidColorBrush(idealForegroundColor);
  20. foreGroundBrush.Freeze();
  21. return foreGroundBrush;
  22. }
  23. return Brushes.White;
  24. }
  25.  
  26. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  27. {
  28. return DependencyProperty.UnsetValue;
  29. }
  30. }

  PercentToAngleConverter.cs代码:

  1. /// <summary>
  2. /// 百分比转换为角度值
  3. /// </summary>
  4. public class PercentToAngleConverter : IValueConverter
  5. {
  6. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  7. {
  8. var percent = value.ToSafeString().ToDouble();
  9. if (percent >= ) return 360.0D;
  10. return percent * ;
  11. }
  12.  
  13. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  14. {
  15. throw new NotImplementedException();
  16. }
  17. }

  ThicknessToDoubleConverter.cs代码:

  1. /// <summary>
  2. /// 获取Thickness固定值double
  3. /// </summary>
  4. public class ThicknessToDoubleConverter : IValueConverter
  5. {
  6. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  7. {
  8. var thickness = (Thickness)value;
  9. return thickness.Left;
  10. }
  11.  
  12. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  13. {
  14. return DependencyProperty.UnsetValue;
  15. }
  16. }

  TreeViewMarginConverter.cs代码:

  1. /// <summary>
  2. /// 计算树节点的左缩进位置
  3. /// </summary>
  4. public class TreeViewMarginConverter : IValueConverter
  5. {
  6. public double Length { get; set; }
  7.  
  8. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  9. {
  10. var item = value as TreeViewItem;
  11. if (item == null)
  12. return new Thickness();
  13. int dep = this.GetDepth(item);
  14. return new Thickness(Length * dep, , , );
  15. }
  16.  
  17. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  18. {
  19. return DependencyProperty.UnsetValue;
  20. }
  21.  
  22. public int GetDepth(TreeViewItem item)
  23. {
  24. TreeViewItem parent;
  25. while ((parent = GetParent(item)) != null)
  26. {
  27. return GetDepth(parent) + ;
  28. }
  29. return ;
  30. }
  31.  
  32. private TreeViewItem GetParent(TreeViewItem item)
  33. {
  34. var parent = item != null ? VisualTreeHelper.GetParent(item) : null;
  35. while (parent != null && !(parent is TreeViewItem || parent is TreeView))
  36. {
  37. parent = VisualTreeHelper.GetParent(parent);
  38. }
  39. return parent as TreeViewItem;
  40. }
  41. }

  TrueToFalseConverter.cs代码:

  1. /// <summary>
  2. /// 这是一个颠倒黑白的世界
  3. /// </summary>
  4. public sealed class TrueToFalseConverter : IValueConverter
  5. {
  6. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  7. {
  8. var v = (bool)value;
  9. return !v;
  10. }
  11.  
  12. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  13. {
  14. throw new NotImplementedException();
  15. }
  16. }

  为了使用简单,对常用的转换器定义了静态变量的引用:

  1. /// <summary>
  2. /// 常用转换器的静态引用
  3. /// 使用实例:Converter={x:Static local:XConverter.TrueToFalseConverter}
  4. /// </summary>
  5. public sealed class XConverter
  6. {
  7. public static BooleanToVisibilityConverter BooleanToVisibilityConverter
  8. {
  9. get { return Singleton<BooleanToVisibilityConverter>.GetInstance(); }
  10. }
  11.  
  12. public static TrueToFalseConverter TrueToFalseConverter
  13. {
  14. get { return Singleton<TrueToFalseConverter>.GetInstance(); }
  15. }
  16.  
  17. public static ThicknessToDoubleConverter ThicknessToDoubleConverter
  18. {
  19. get { return Singleton<ThicknessToDoubleConverter>.GetInstance(); }
  20. }
  21. public static BackgroundToForegroundConverter BackgroundToForegroundConverter
  22. {
  23. get { return Singleton<BackgroundToForegroundConverter>.GetInstance(); }
  24. }
  25. public static TreeViewMarginConverter TreeViewMarginConverter
  26. {
  27. get { return Singleton<TreeViewMarginConverter>.GetInstance(); }
  28. }
  29.  
  30. public static PercentToAngleConverter PercentToAngleConverter
  31. {
  32. get { return Singleton<PercentToAngleConverter>.GetInstance(); }
  33. }
  34. }

  然后使用时就不用在xaml中声明资源了,通过静态引用的方式使用,就是这样的:

EndAngle="{TemplateBinding Value, Converter={x:Static local:XConverter.PercentToAngleConverter}}"

2.6其他样式

  Share.xaml:

  1. <!--下拉按钮样式:ToggleButton样式 ['tɑɡl] 开关,触发器;拴扣;[船] 套索钉-->
  2. <!--图标大小:local:ControlAttachProperty.FIconSize-->
  3. <!--图标边距:local:ControlAttachProperty.FIconMargin-->
  4. <!--图标:local:ControlAttachProperty.FIcon-->
  5. <Style TargetType="{x:Type ToggleButton}" x:Key="ComboToggleButton">
  6. <Setter Property="Foreground" Value="{StaticResource TextForeground}" />
  7. <Setter Property="local:ControlAttachProperty.FIconSize" Value="18"/>
  8. <Setter Property="local:ControlAttachProperty.FIconMargin" Value="0,1,3,1"/>
  9. <Setter Property="local:ControlAttachProperty.FIcon" Value=""/>
  10. <Setter Property="SnapsToDevicePixels" Value="True" />
  11. <Setter Property="Template">
  12. <Setter.Value>
  13. <ControlTemplate TargetType="{x:Type ToggleButton}">
  14. <Grid x:Name="Grid">
  15. <Grid.ColumnDefinitions>
  16. <ColumnDefinition Width="*"/>
  17. <ColumnDefinition Width="Auto"/>
  18. </Grid.ColumnDefinitions>
  19. <Border Background="{TemplateBinding Background}" x:Name="Bg" Grid.ColumnSpan="2" Margin="0,1,1,1"
  20. SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Opacity="0.3"/>
  21. <TextBlock Grid.Column="1" x:Name="FIcon" FontSize="{Binding Path=(local:ControlAttachProperty.FIconSize),RelativeSource={RelativeSource TemplatedParent}}"
  22. Text="{TemplateBinding local:ControlAttachProperty.FIcon}"
  23. local:ControlAttachProperty.AllowsAnimation="{TemplateBinding IsChecked}"
  24. Foreground="{TemplateBinding Foreground}" Style="{StaticResource FIcon}"
  25. Margin="{TemplateBinding local:ControlAttachProperty.FIconMargin}"/>
  26. </Grid>
  27. <!--z触发器-->
  28. <ControlTemplate.Triggers>
  29. <Trigger Property="IsMouseOver" Value="True">
  30. <Setter Property="Foreground" Value="{StaticResource MouseOverForeground}" />
  31. <Setter Property="Opacity" TargetName="Bg" Value="0.55" />
  32. </Trigger>
  33. <Trigger Property="IsPressed" Value="True">
  34. <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
  35. <Setter Property="Opacity" TargetName="Bg" Value="0.6" />
  36. </Trigger>
  37. <Trigger Property="IsChecked" Value="True">
  38. <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
  39. <Setter Property="Opacity" TargetName="Bg" Value="0.6" />
  40. </Trigger>
  41. <Trigger Property="IsEnabled" Value="false">
  42. <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="Grid"/>
  43. </Trigger>
  44. </ControlTemplate.Triggers>
  45. </ControlTemplate>
  46. </Setter.Value>
  47. </Setter>
  48. </Style>
  49.  
  50. <!--编辑状态文本框样式-->
  51. <Style TargetType="{x:Type TextBox}" x:Key="EditableTextBoxStyle">
  52. <Setter Property="Margin" Value="1"/>
  53. <Setter Property="Padding" Value="0"/>
  54. <Setter Property="BorderThickness" Value="0"/>
  55. <Setter Property="Background" Value="{x:Null}"/>
  56. <Setter Property="MaxLength" Value="2048"/>
  57. <Setter Property="Foreground" Value="{StaticResource TextForeground}"/>
  58. <Setter Property="ContextMenu" Value="{DynamicResource TextBoxContextMenu}" />
  59. <Setter Property="SelectionBrush" Value="{StaticResource TextSelectionBrush}" />
  60. <Setter Property="FontSize" Value="{StaticResource FontSize}"></Setter>
  61. <Setter Property="FontFamily" Value="{StaticResource FontFamily}"></Setter>
  62. <Setter Property="Focusable" Value="True"/>
  63. <Setter Property="CaretBrush" Value="{StaticResource TextForeground}" />
  64. <Setter Property="VerticalAlignment" Value="Center" />
  65. <Setter Property="SnapsToDevicePixels" Value="True"></Setter>
  66. <Style.Triggers>
  67. <Trigger Property="IsReadOnly" Value="True">
  68. <Setter Property="Opacity" Value="{StaticResource ReadonlyOpacity}"></Setter>
  69. </Trigger>
  70. <Trigger Property="IsEnabled" Value="False">
  71. <Setter Property="Opacity" Value="{StaticResource DisableOpacity}"></Setter>
  72. </Trigger>
  73. </Style.Triggers>
  74. </Style>

  Global.xaml

  1. <!--TextBlock-->
  2. <Style TargetType="{x:Type TextBlock}">
  3. <Setter Property="Foreground" Value="{StaticResource TextForeground}"/>
  4. <Setter Property="FontFamily" Value="{StaticResource FontFamily}"/>
  5. <Setter Property="FontSize" Value="{StaticResource FontSize}"/>
  6. </Style>
  7.  
  8. <!--ToolTip-->
  9. <Style TargetType="{x:Type ToolTip}">
  10. <Setter Property="Foreground" Value="{StaticResource TextForeground}"/>
  11. <Setter Property="FontFamily" Value="{StaticResource FontFamily}"/>
  12. <Setter Property="FontSize" Value="{StaticResource FontSize}"/>
  13. <Setter Property="Background" Value="{StaticResource HeaderBackground}"/>
  14. <Setter Property="BorderBrush" Value="{StaticResource FocusBorderBrush}"/>
  15. <Setter Property="BorderThickness" Value="1"/>
  16. <Setter Property="Template">
  17. <Setter.Value>
  18. <ControlTemplate TargetType="{x:Type ToolTip}">
  19. <Border CornerRadius="2" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}">
  20. <ContentPresenter Margin="8,5,8,5"/>
  21. </Border>
  22. </ControlTemplate>
  23. </Setter.Value>
  24. </Setter>
  25. </Style>

  TablControl 的样式,TablControl.xaml

  1. <Style x:Key="FIconTabItemStyle" TargetType="{x:Type TabItem}">
  2. <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
  3. <Setter Property="VerticalContentAlignment" Value="Stretch"/>
  4. <Setter Property="Background" Value="{StaticResource ButtonBackground}"/>
  5. <Setter Property="Foreground" Value="{StaticResource TextForeground}" />
  6. <Setter Property="local:ControlAttachProperty.FIcon" Value=""/>
  7. <Setter Property="local:ControlAttachProperty.FIconSize" Value="26"/>
  8. <Setter Property="local:ControlAttachProperty.CornerRadius" Value="0"/>
  9. <Setter Property="local:ControlAttachProperty.FIconMargin" Value="0,0,2,0"/>
  10. <Setter Property="local:ControlAttachProperty.FocusBackground" Value="{StaticResource ButtonPressedBackground}"/>
  11. <Setter Property="local:ControlAttachProperty.FocusForeground" Value="{StaticResource ButtonMouseOverForeground}"/>
  12. <Setter Property="local:ControlAttachProperty.MouseOverBackground" Value="{StaticResource ButtonMouseOverBackground}"/>
  13. <Setter Property="local:ControlAttachProperty.MouseOverForeground" Value="{StaticResource ButtonPressedForeground}"/>
  14. <Setter Property="MinHeight" Value="20"/>
  15. <Setter Property="MinWidth" Value="20"/>
  16. <Setter Property="Margin" Value="0"/>
  17. <Setter Property="Padding" Value="3"/>
  18. <Setter Property="Template">
  19. <Setter.Value>
  20. <ControlTemplate TargetType="{x:Type TabItem}">
  21. <Border x:Name="border" Margin="{TemplateBinding Margin}" SnapsToDevicePixels="True" ToolTip="{TemplateBinding ToolTip}"
  22. CornerRadius="{TemplateBinding local:ControlAttachProperty.CornerRadius}" Background="{TemplateBinding Background}">
  23. <StackPanel VerticalAlignment="Center" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Orientation="Horizontal">
  24. <TextBlock Style="{StaticResource FIcon}" Text="{TemplateBinding local:ControlAttachProperty.FIcon}" Margin="{TemplateBinding local:ControlAttachProperty.FIconMargin}"
  25. FontSize="{TemplateBinding local:ControlAttachProperty.FIconSize}" Foreground="{TemplateBinding Foreground}"/>
  26. <TextBlock x:Name="txtheader" VerticalAlignment="Center" Text="{TemplateBinding Header}" Foreground="{TemplateBinding Foreground}"/>
  27. </StackPanel>
  28. </Border>
  29. <ControlTemplate.Triggers>
  30. <Trigger Property="IsMouseOver" Value="true">
  31. <Setter Property="Background" Value="{Binding Path=(local:ControlAttachProperty.MouseOverBackground),RelativeSource={RelativeSource Self}}"/>
  32. <Setter Property="Foreground" Value="{Binding Path=(local:ControlAttachProperty.MouseOverForeground),RelativeSource={RelativeSource Self}}"/>
  33. </Trigger>
  34. <Trigger Property="IsSelected" Value="true">
  35. <Setter Property="Background" Value="{Binding Path=(local:ControlAttachProperty.FocusBackground),RelativeSource={RelativeSource Self}}"/>
  36. <Setter Property="Foreground" Value="{Binding Path=(local:ControlAttachProperty.FocusForeground),RelativeSource={RelativeSource Self}}"/>
  37. </Trigger>
  38. </ControlTemplate.Triggers>
  39. </ControlTemplate>
  40. </Setter.Value>
  41. </Setter>
  42. </Style>
  43.  
  44. <Style x:Key="LeftTabControl" TargetType="{x:Type TabControl}">
  45. <Setter Property="Padding" Value="0"/>
  46. <Setter Property="Background" Value="Transparent" />
  47. <Setter Property="HorizontalContentAlignment" Value="Center"/>
  48. <Setter Property="VerticalContentAlignment" Value="Center"/>
  49. <Setter Property="SnapsToDevicePixels" Value="True" />
  50. <Setter Property="BorderThickness" Value="1" />
  51. <Setter Property="BorderBrush" Value="{StaticResource ControlBorderBrush}" />
  52. <Setter Property="ItemContainerStyle" Value="{DynamicResource FIconTabItemStyle}"/>
  53. <Setter Property="TabStripPlacement" Value="Left"></Setter>
  54. <Setter Property="local:ControlAttachProperty.FocusBackground" Value="{StaticResource ButtonPressedBackground}"/>
  55. <Setter Property="Template">
  56. <Setter.Value>
  57. <ControlTemplate TargetType="{x:Type TabControl}">
  58. <Grid x:Name="PART_Root" Margin="{TemplateBinding Padding}" >
  59. <Grid.ColumnDefinitions>
  60. <ColumnDefinition Width="Auto"/>
  61. <ColumnDefinition Width="*"/>
  62. </Grid.ColumnDefinitions>
  63.  
  64. <Border BorderBrush="{TemplateBinding local:ControlAttachProperty.FocusBackground}" BorderThickness="0,0,2,0" >
  65. <StackPanel x:Name="HeaderPanel" Margin="0,5,0,5" Orientation="Vertical" IsItemsHost="True" ></StackPanel>
  66. </Border>
  67.  
  68. <Border x:Name="ContentPanel" Grid.Column="1" BorderBrush="{TemplateBinding BorderBrush}"
  69. BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
  70. KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2"
  71. KeyboardNavigation.TabNavigation="Local" Width="Auto">
  72. <ContentPresenter ContentSource="SelectedContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Width="Auto" />
  73. </Border>
  74. </Grid>
  75. </ControlTemplate>
  76. </Setter.Value>
  77. </Setter>
  78. </Style>
  79.  
  80. <Style x:Key="TopTabControl" TargetType="{x:Type TabControl}">
  81. <Setter Property="Padding" Value="0"/>
  82. <Setter Property="BorderThickness" Value="1"/>
  83. <Setter Property="Background" Value="Transparent" />
  84. <Setter Property="HorizontalContentAlignment" Value="Center"/>
  85. <Setter Property="VerticalContentAlignment" Value="Center"/>
  86. <Setter Property="SnapsToDevicePixels" Value="True" />
  87. <Setter Property="ItemContainerStyle" Value="{StaticResource FIconTabItemStyle}"/>
  88. <Setter Property="BorderBrush" Value="{StaticResource ControlBorderBrush}" />
  89. <Setter Property="TabStripPlacement" Value="Top"></Setter>
  90. <Setter Property="local:ControlAttachProperty.FocusBackground" Value="{StaticResource ButtonPressedBackground}"/>
  91. <Setter Property="Template">
  92. <Setter.Value>
  93. <ControlTemplate TargetType="{x:Type TabControl}">
  94. <Grid x:Name="PART_Root" Margin="{TemplateBinding Padding}" >
  95. <Grid.RowDefinitions>
  96. <RowDefinition Height="Auto"/>
  97. <RowDefinition Height="*"/>
  98. </Grid.RowDefinitions>
  99.  
  100. <Border BorderBrush="{TemplateBinding local:ControlAttachProperty.FocusBackground}" BorderThickness="0,0,0,2" >
  101. <StackPanel x:Name="HeaderPanel" Margin="5,0,5,0" Orientation="Horizontal" IsItemsHost="True" ></StackPanel>
  102. </Border>
  103.  
  104. <Border x:Name="ContentPanel" Grid.Row="1" BorderBrush="{TemplateBinding BorderBrush}"
  105. BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
  106. KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2"
  107. KeyboardNavigation.TabNavigation="Local" Width="Auto">
  108. <ContentPresenter ContentSource="SelectedContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Width="Auto"/>
  109. </Border>
  110. </Grid>
  111. </ControlTemplate>
  112. </Setter.Value>
  113. </Setter>
  114. </Style>

  ToggleButton的样式资源

  1. <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  2. xmlns:local="clr-namespace:XLY.Framework.Controls"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  4.  
  5. <Style TargetType="{x:Type ToggleButton}" x:Key="DefaultToggleButton">
  6. <Setter Property="Foreground" Value="{StaticResource TextForeground}" />
  7. <Setter Property="SnapsToDevicePixels" Value="True" />
  8. <Setter Property="Template">
  9. <Setter.Value>
  10. <ControlTemplate TargetType="{x:Type ToggleButton}">
  11. <Grid x:Name="Grid" Margin="{TemplateBinding Padding}">
  12. <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
  13. </Grid>
  14. <!--z触发器-->
  15. <ControlTemplate.Triggers>
  16. <Trigger Property="IsMouseOver" Value="True">
  17. <Setter Property="Foreground" Value="{StaticResource MouseOverForeground}" />
  18. </Trigger>
  19. <Trigger Property="IsPressed" Value="True">
  20. <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
  21. </Trigger>
  22. <Trigger Property="IsChecked" Value="True">
  23. <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
  24. </Trigger>
  25. <Trigger Property="IsEnabled" Value="false">
  26. <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="Grid"/>
  27. </Trigger>
  28. </ControlTemplate.Triggers>
  29. </ControlTemplate>
  30. </Setter.Value>
  31. </Setter>
  32. </Style>
  33.  
  34. <Style TargetType="{x:Type ToggleButton}" x:Key="FIconToggleButton">
  35. <Setter Property="Foreground" Value="{StaticResource TextForeground}" />
  36. <Setter Property="local:ControlAttachProperty.FIconSize" Value="20"/>
  37. <Setter Property="local:ControlAttachProperty.FIconMargin" Value="1"/>
  38. <Setter Property="local:ControlAttachProperty.FIcon" Value=""/>
  39. <Setter Property="SnapsToDevicePixels" Value="True" />
  40. <Setter Property="Padding" Value="0" />
  41. <Setter Property="Template">
  42. <Setter.Value>
  43. <ControlTemplate TargetType="{x:Type ToggleButton}">
  44. <Grid x:Name="Grid" Margin="{TemplateBinding Padding}">
  45. <TextBlock x:Name="FIcon" FontSize="{Binding Path=(local:ControlAttachProperty.FIconSize),RelativeSource={RelativeSource TemplatedParent}}"
  46. Text="{TemplateBinding local:ControlAttachProperty.FIcon}"
  47. Foreground="{TemplateBinding Foreground}" Style="{StaticResource FIcon}"
  48. Margin="{TemplateBinding local:ControlAttachProperty.FIconMargin}"/>
  49. </Grid>
  50. <!--z触发器-->
  51. <ControlTemplate.Triggers>
  52. <Trigger Property="IsMouseOver" Value="True">
  53. <Setter Property="Foreground" Value="{StaticResource MouseOverForeground}" />
  54. </Trigger>
  55. <Trigger Property="IsPressed" Value="True">
  56. <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
  57. </Trigger>
  58. <Trigger Property="IsChecked" Value="True">
  59. <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
  60. </Trigger>
  61. <Trigger Property="IsEnabled" Value="false">
  62. <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="Grid"/>
  63. </Trigger>
  64. </ControlTemplate.Triggers>
  65. </ControlTemplate>
  66. </Setter.Value>
  67. </Setter>
  68. </Style>
  69.  
  70. </ResourceDictionary>

Github项目地址https://github.com/kwonganding/wpf.controls

版权所有,文章来源:http://www.cnblogs.com/anding

个人能力有限,本文内容仅供学习、探讨,欢迎指正、交流。

WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享的更多相关文章

  1. WPF自定义控件与样式(15)-终结篇

    原文:WPF自定义控件与样式(15)-终结篇 系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与 ...

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

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

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

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

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

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

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

    一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要是对文本输入控件进行样式开发,及相关扩展功能开发,主要内容包括: 基本文 ...

  6. 【转】WPF自定义控件与样式(2)-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等 还是先看看效果图吧:   定义Button按钮名称叫FButton,主要是集成了 ...

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

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

  8. WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

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

  9. WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式

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

随机推荐

  1. [置顶]PADS PCB功能使用技巧系列之NO.002- 如何走差分线?

    差分信号在高速电路设计中应用越来越广泛,如USB.HDMI.PCI.DDR*等,承载差分信号的差分线主要优势有:抗干扰能力强,能有效抑制EMI.时序定位精确等,对于PCB工程师来说,最关注的是如何确保 ...

  2. mysql 性能配置优化

    修改mysql配置文件 my.cnf ,内容如下: [mysqld]datadir=/data/mysql/datasocket=/var/lib/mysql/mysql.sockuser=mysql ...

  3. 使用yum时,保留下载包设置

    配置yum保留已经下载的rpm包,供以后升级或重新安装时使用.修改/etc/yum.conf[main]cachedir=/home/soft1/yumcachekeepcache=1debuglev ...

  4. Google one联合联发科,国内低端智能机方案怎么办?

    欢迎转载opendevkit文章, 文章原始地址: http://www.opendevkit.com/?e=46 Google在Google I/O大会, 发布的Android One,由于看重的是 ...

  5. 工具mark

    http://zh.snipaste.com/ 截图工具 https://brookhong.github.io/2014/04/28/keycast-on-windows-cn.html 按键显示 ...

  6. input只读属性区别

    readonly disabled 相同点:都是禁止输入 不同点:readonly属性会把该input提交到form表单 disabled属性不会把该input提交到form表单

  7. Android 自定义View 三板斧之三——重写View来实现全新控件

    通常情况下,Android实现自定义控件无非三种方式. Ⅰ.继承现有控件,对其控件的功能进行拓展. Ⅱ.将现有控件进行组合,实现功能更加强大控件. Ⅲ.重写View实现全新的控件 本文来讨论最难的一种 ...

  8. 推荐几款自己写博客使用的Ubuntu软件

    使用Ubuntu桌面有段时间,到现在也写过几篇博客了,期间用到的几款好用的软件推荐给大家.1. 图片简单编辑软件gthumbubuntu默认提供shotwell查看图片,类似与windows的图片查看 ...

  9. .Net Core CLI在CentOS7的安装及使用简介

    1. 安装libunwind cd /usr/local/src wget http://download.savannah.gnu.org/releases/libunwind/libunwind- ...

  10. 【转】一个lucene的官网例子

    创建索引: import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import jav ...