控件cs文件

  1. using System.ComponentModel;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4. using System.Windows.Controls.Primitives;
  5. using System.Windows.Markup;
  6. using System.Windows.Media;
  7.  
  8. namespace Controls
  9. {
  10.  
  11. [TemplatePart(Name = "PART_DropDown", Type = typeof(System.Windows.Controls.Button))]
  12. [ContentProperty("Items")]
  13. [DefaultProperty("Items")]
  14. public class MyButton: System.Windows.Controls.Button
  15. {
  16. public static readonly DependencyProperty HorizontalOffsetProperty;
  17. public static readonly DependencyProperty IsContextMenuOpenProperty;
  18. public static readonly DependencyProperty ModeProperty;
  19. public static readonly DependencyProperty PlacementProperty;
  20. public static readonly DependencyProperty PlacementRectangleProperty;
  21. public static readonly DependencyProperty VerticalOffsetProperty;
  22.  
  23. public static readonly DependencyProperty ImageSourceProperty =
  24. DependencyProperty.Register("ImageSource", typeof(string), typeof(MyButton), new PropertyMetadata(""));
  25. public static readonly DependencyProperty ImageSourceChangeProperty =
  26. DependencyProperty.Register("ImageSourceChange", typeof(string), typeof(MyButton), new PropertyMetadata(""));
  27.  
  28. /// <summary>
  29. /// Static Constructor
  30. /// </summary>
  31. static MyButton()
  32. {
  33. DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
  34. IsContextMenuOpenProperty = DependencyProperty.Register("IsContextMenuOpen", typeof(bool), typeof(MyButton), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsContextMenuOpenChanged)));
  35. ModeProperty = DependencyProperty.Register("Mode", typeof(MyButtonMode), typeof(MyButton), new FrameworkPropertyMetadata(MyButtonMode.Split));
  36.  
  37. PlacementProperty = ContextMenuService.PlacementProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(PlacementMode.Bottom, new PropertyChangedCallback(OnPlacementChanged)));
  38. PlacementRectangleProperty = ContextMenuService.PlacementRectangleProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(Rect.Empty, new PropertyChangedCallback(OnPlacementRectangleChanged)));
  39. HorizontalOffsetProperty = ContextMenuService.HorizontalOffsetProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(0.0, new PropertyChangedCallback(OnHorizontalOffsetChanged)));
  40. VerticalOffsetProperty = ContextMenuService.VerticalOffsetProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(0.0, new PropertyChangedCallback(OnVerticalOffsetChanged)));
  41. }
  42.  
  43. /*
  44. * Overrides
  45. *
  46. */
  47. /// <summary>
  48. /// OnApplyTemplate override, set up the click event for the dropdown if present in the template
  49. /// </summary>
  50. public override void OnApplyTemplate()
  51. {
  52. base.OnApplyTemplate();
  53.  
  54. // set up the click event handler for the dropdown button
  55. System.Windows.Controls.Primitives.ButtonBase dropDown = this.Template.FindName("PART_DropDown", this) as System.Windows.Controls.Primitives.ButtonBase;
  56. if (dropDown != null)
  57. dropDown.Click += Dropdown_Click;
  58. }
  59.  
  60. /// <summary>
  61. /// Handles the Base Buttons OnClick event
  62. /// </summary>
  63. protected override void OnClick()
  64. {
  65. switch (Mode)
  66. {
  67. case MyButtonMode.Dropdown:
  68. OnDropdown();
  69. break;
  70.  
  71. default:
  72. base.OnClick(); // forward on the Click event to the user
  73. break;
  74. }
  75. }
  76.  
  77. /*
  78. * Properties
  79. *
  80. */
  81.  
  82. /// <summary>
  83. /// The Split Button's Items property maps to the base classes ContextMenu.Items property
  84. /// </summary>
  85. public ItemCollection Items
  86. {
  87. get
  88. {
  89. EnsureContextMenuIsValid();
  90. return this.ContextMenu.Items;
  91. }
  92. }
  93.  
  94. /*
  95. * DependencyProperty CLR wrappers
  96. *
  97. */
  98.  
  99. public string ImageSource
  100. {
  101. get { return (string)GetValue(ImageSourceProperty); }
  102. set { SetValue(ImageSourceProperty, value); }
  103. }
  104.  
  105. public string ImageSourceChange
  106. {
  107. get { return (string)GetValue(ImageSourceChangeProperty); }
  108. set { SetValue(ImageSourceChangeProperty, value); }
  109. }
  110.  
  111. /// <summary>
  112. /// Gets or sets the IsContextMenuOpen property.
  113. /// </summary>
  114. public bool IsContextMenuOpen
  115. {
  116. get { return (bool)GetValue(IsContextMenuOpenProperty); }
  117. set { SetValue(IsContextMenuOpenProperty, value); }
  118. }
  119.  
  120. /// <summary>
  121. /// Placement of the Context menu
  122. /// </summary>
  123. public PlacementMode Placement
  124. {
  125. get { return (PlacementMode)GetValue(PlacementProperty); }
  126. set { SetValue(PlacementProperty, value); }
  127. }
  128.  
  129. /// <summary>
  130. /// PlacementRectangle of the Context menu
  131. /// </summary>
  132. public Rect PlacementRectangle
  133. {
  134. get { return (Rect)GetValue(PlacementRectangleProperty); }
  135. set { SetValue(PlacementRectangleProperty, value); }
  136. }
  137.  
  138. /// <summary>
  139. /// HorizontalOffset of the Context menu
  140. /// </summary>
  141. public double HorizontalOffset
  142. {
  143. get { return (double)GetValue(HorizontalOffsetProperty); }
  144. set { SetValue(HorizontalOffsetProperty, value); }
  145. }
  146.  
  147. /// <summary>
  148. /// VerticalOffset of the Context menu
  149. /// </summary>
  150. public double VerticalOffset
  151. {
  152. get { return (double)GetValue(VerticalOffsetProperty); }
  153. set { SetValue(VerticalOffsetProperty, value); }
  154. }
  155.  
  156. /// <summary>
  157. /// Defines the Mode of operation of the Button
  158. /// </summary>
  159. /// <remarks>
  160. /// The MyButton two Modes are
  161. /// Split (default), - the button has two parts, a normal button and a dropdown which exposes the ContextMenu
  162. /// Dropdown - the button acts like a combobox, clicking anywhere on the button opens the Context Menu
  163. /// </remarks>
  164. public MyButtonMode Mode
  165. {
  166. get { return (MyButtonMode)GetValue(ModeProperty); }
  167. set { SetValue(ModeProperty, value); }
  168. }
  169.  
  170. /*
  171. * DependencyPropertyChanged callbacks
  172. *
  173. */
  174.  
  175. private static void OnIsContextMenuOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  176. {
  177. MyButton s = (MyButton)d;
  178. s.EnsureContextMenuIsValid();
  179.  
  180. if (!s.ContextMenu.HasItems)
  181. return;
  182.  
  183. bool value = (bool)e.NewValue;
  184.  
  185. if (value && !s.ContextMenu.IsOpen)
  186. s.ContextMenu.IsOpen = true;
  187. else if (!value && s.ContextMenu.IsOpen)
  188. s.ContextMenu.IsOpen = false;
  189. }
  190.  
  191. /// <summary>
  192. /// Placement Property changed callback, pass the value through to the buttons context menu
  193. /// </summary>
  194. private static void OnPlacementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  195. {
  196. MyButton s = d as MyButton;
  197. if (s == null) return;
  198.  
  199. s.EnsureContextMenuIsValid();
  200. s.ContextMenu.Placement = (PlacementMode)e.NewValue;
  201. }
  202.  
  203. /// <summary>
  204. /// PlacementRectangle Property changed callback, pass the value through to the buttons context menu
  205. /// </summary>
  206. private static void OnPlacementRectangleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  207. {
  208. MyButton s = d as MyButton;
  209. if (s == null) return;
  210.  
  211. s.EnsureContextMenuIsValid();
  212. s.ContextMenu.PlacementRectangle = (Rect)e.NewValue;
  213. }
  214.  
  215. /// <summary>
  216. /// HorizontalOffset Property changed callback, pass the value through to the buttons context menu
  217. /// </summary>
  218. private static void OnHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  219. {
  220. MyButton s = d as MyButton;
  221. if (s == null) return;
  222.  
  223. s.EnsureContextMenuIsValid();
  224. s.ContextMenu.HorizontalOffset = (double)e.NewValue;
  225. }
  226.  
  227. /// <summary>
  228. /// VerticalOffset Property changed callback, pass the value through to the buttons context menu
  229. /// </summary>
  230. private static void OnVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  231. {
  232. MyButton s = d as MyButton;
  233. if (s == null) return;
  234.  
  235. s.EnsureContextMenuIsValid();
  236. s.ContextMenu.VerticalOffset = (double)e.NewValue;
  237. }
  238.  
  239. /*
  240. * Helper Methods
  241. *
  242. */
  243.  
  244. /// <summary>
  245. /// Make sure the Context menu is not null
  246. /// </summary>
  247. private void EnsureContextMenuIsValid()
  248. {
  249. if (this.ContextMenu == null)
  250. {
  251. this.ContextMenu = new System.Windows.Controls.ContextMenu();
  252. this.ContextMenu.PlacementTarget = this;
  253. this.ContextMenu.Placement = Placement;
  254.  
  255. this.ContextMenu.Opened += ((sender, routedEventArgs) => IsContextMenuOpen = true);
  256. this.ContextMenu.Closed += ((sender, routedEventArgs) => IsContextMenuOpen = false);
  257. }
  258. }
  259.  
  260. private void OnDropdown()
  261. {
  262. EnsureContextMenuIsValid();
  263. if (!this.ContextMenu.HasItems)
  264. return;
  265.  
  266. this.ContextMenu.IsOpen = !IsContextMenuOpen; // open it if closed, close it if open
  267. }
  268.  
  269. /*
  270. * Events
  271. *
  272. */
  273.  
  274. /// <summary>
  275. /// Event Handler for the Drop Down Button's Click event
  276. /// </summary>
  277. /// <param name="sender"></param>
  278. /// <param name="e"></param>
  279. private void Dropdown_Click(object sender, RoutedEventArgs e)
  280. {
  281. OnDropdown();
  282. e.Handled = true;
  283. }
  284. }
  285. }

控件xaml

  1. <ResourceDictionary
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:comm="clr-namespace:Controls">
  5.  
  6. <Style x:Key="ButtonFocusVisual">
  7. <Setter Property="Control.Template">
  8. <Setter.Value>
  9. <ControlTemplate>
  10. <Rectangle
  11. Margin=""
  12. SnapsToDevicePixels="true"
  13. Stroke="Transparent"
  14. StrokeDashArray="1 2"
  15. StrokeThickness="" />
  16. </ControlTemplate>
  17. </Setter.Value>
  18. </Setter>
  19. </Style>
  20. <Style TargetType="Button">
  21. <Setter Property="Foreground" Value="#D5D5D5" />
  22. <Setter Property="FontSize" Value="" />
  23. <Setter Property="Template">
  24. <Setter.Value>
  25. <ControlTemplate TargetType="Button">
  26. <Image
  27. x:Name="image"
  28. HorizontalAlignment="Center"
  29. VerticalAlignment="Center"
  30. Source="{Binding Path=ImageSource, RelativeSource={RelativeSource AncestorType={x:Type comm:MyButton}}}" />
  31.  
  32. <ControlTemplate.Triggers>
  33. <Trigger Property="IsMouseOver" Value="True">
  34. <Setter TargetName="image" Property="Source" Value="{Binding Path=ImageSourceChange, RelativeSource={RelativeSource AncestorType={x:Type comm:MyButton}}}" />
  35. </Trigger>
  36. </ControlTemplate.Triggers>
  37. </ControlTemplate>
  38. </Setter.Value>
  39. </Setter>
  40. </Style>
  41. <Style TargetType="{x:Type comm:MyButton}">
  42. <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}" />
  43. <Setter Property="FontSize" Value="" />
  44. <Setter Property="Foreground" Value="#D5D5D5" />
  45. <Setter Property="FontFamily" Value="微软雅黑" />
  46. <Setter Property="HorizontalContentAlignment" Value="Center" />
  47. <Setter Property="VerticalContentAlignment" Value="Center" />
  48. <Setter Property="Padding" Value="" />
  49. <Setter Property="Template">
  50. <Setter.Value>
  51. <ControlTemplate TargetType="{x:Type comm:MyButton}">
  52. <Border
  53. x:Name="grid"
  54. HorizontalAlignment="Stretch"
  55. VerticalAlignment="Stretch"
  56. Background="Transparent"
  57. CornerRadius="">
  58.  
  59. <Button x:Name="PART_DropDown" />
  60. </Border>
  61. <ControlTemplate.Triggers>
  62.  
  63. <Trigger SourceName="PART_DropDown" Property="IsMouseOver" Value="true">
  64. <Setter TargetName="PART_DropDown" Property="Opacity" Value="" />
  65. <Setter TargetName="grid" Property="Background" Value="Transparent" />
  66. </Trigger>
  67. <Trigger Property="IsEnabled" Value="false">
  68. <Setter Property="Foreground" Value="#ADADAD" />
  69. </Trigger>
  70. </ControlTemplate.Triggers>
  71. </ControlTemplate>
  72. </Setter.Value>
  73. </Setter>
  74. </Style>
  75. </ResourceDictionary>

页面使用:

  1. <comm:MyButton
  2. Width=""
  3. Height=""
  4. ImageSource="/control;component/Icons/picture2.png"
  5. ImageSourceChange="/control;component/Icons/picture1.png">
  6.  
  7. </comm:MyButton>

WPF自定义控件 依赖属性绑定的更多相关文章

  1. WPF自定义控件的自定义属性绑定后不更新问题

    原文:WPF自定义控件的自定义属性绑定后不更新问题 需要在绑定时设置属性变更触发 UpdateSourceTrigger=PropertyChanged 例如: <Border CornerRa ...

  2. WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性

    原文:WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性 如果你要自定义一个图片按钮控件,那么如何在主窗体绑定这个控件上图片的Source呢? ...

  3. WPF的依赖属性和附加属性(用法解释较全)

    转:https://www.cnblogs.com/zhili/p/WPFDependencyProperty.html 一.引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己 ...

  4. WPF的依赖属性

    Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR)属性的功能,这些服务通常统称为 WPF 属性系统.由 WPF 属 ...

  5. wpf 的依赖属性只能在loaded 事件之后才能取到

    wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的  InitializeComponent(); 之后取不到 wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的  ...

  6. WPF 中依赖属性的继承(Inherits)

    WPF中依赖属性的值是是可以设置为可继承(Inherits)的,这种模式下,父节点的依赖属性会将其值传递给子节点.例如,数据绑定中经常使用的DataContextProperty: var host ...

  7. WPF利用依赖属性和命令编写自定义控件

    以实例讲解(大部分讲解在代码中) 1,新建一个WPF项目,添加一个用户控件之后在用户控件里面添加几个控件用作测试, <UserControl x:Class="SelfControlD ...

  8. WPF 使用依赖属性自定义控件

    使用依赖属性自定义控件,依赖属性必须定义在自定义控件中,不能定义在其他文件中 一.先实现一个类继承你要复写的类 using System; using System.Collections.Gener ...

  9. WPF: 只读依赖属性的介绍与实践

    在设计与开发 WPF 自定义控件时,我们常常为会控件添加一些依赖属性以便于绑定或动画等.事实上,除了能够添加正常的依赖属性外,我们还可以为控件添加只读依赖属性(以下统称"只读属性" ...

随机推荐

  1. centos7下python3和pycharm安装

    1.python3安装 直接到官网下载或在以下地址下载让后解压安装 下载地址:https://www.python.org/ftp/python/ 安装参考博客:https://www.cnblogs ...

  2. storm运行服务器一些错误解决、

    java.lang.RuntimeException: Returned channel was actually not established 重启试试 Java.lang.NoSuchMetho ...

  3. Idea SSH框架整合基础代码

    第一步 pom.xml注入jar包依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" ...

  4. 2019-8-30-BAT-脚本判断当前系统是-x86-还是-x64-系统

    title author date CreateTime categories BAT 脚本判断当前系统是 x86 还是 x64 系统 lindexi 2019-08-30 08:47:40 +080 ...

  5. react-native start停止在Loading dependency graph, done.

    在试验的过程中. 发现运行 react-native start会卡住,停留在Loading dependency graph, done. 原因大概是之前运行过 react-native run-a ...

  6. LA4670 Dominating Patterns AC自动机模板

    Dominating Patterns 每次看着别人的代码改成自己的模板都很头大...空间少了个0卡了好久 裸题,用比map + string更高效的vector代替蓝书中的处理方法 #include ...

  7. 国内在Amazon fireTV或者fire平板下载应用(netflix\hulu\YouTube)的方法

    1.首先需要vpn翻墙至U.S. 2.需要一个美国亚马逊账户,并设置收货地址 (Manage Your Fire & Kindle 1-Click Payment Settings ),如果只 ...

  8. Ubuntu下使用sshfs挂载远程目录到本地

    访问局域网中其他Ubuntu机器,在不同机器间跳来跳去,很是麻烦,如果能够把远程目录映射到本地无疑会大大方面使用,就像Windows下的网络映射盘一样.在Linux的世界无疑也会有这种机制和方式,最近 ...

  9. echarts--例子

    echarts使用例子: <script type="text/javascript"> option = { title : {'x': 'center','y':' ...

  10. 让footer始终待在页面底部

    1.把html和body的height属性设为100%;保证content的高度能撑满浏览器; 2.把#content的高度也设置为100% ,但是这里我们使用了“min-height”属性,而不是的 ...