WPF自定义控件 依赖属性绑定
控件cs文件
- using System.ComponentModel;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Controls.Primitives;
- using System.Windows.Markup;
- using System.Windows.Media;
- namespace Controls
- {
- [TemplatePart(Name = "PART_DropDown", Type = typeof(System.Windows.Controls.Button))]
- [ContentProperty("Items")]
- [DefaultProperty("Items")]
- public class MyButton: System.Windows.Controls.Button
- {
- public static readonly DependencyProperty HorizontalOffsetProperty;
- public static readonly DependencyProperty IsContextMenuOpenProperty;
- public static readonly DependencyProperty ModeProperty;
- public static readonly DependencyProperty PlacementProperty;
- public static readonly DependencyProperty PlacementRectangleProperty;
- public static readonly DependencyProperty VerticalOffsetProperty;
- public static readonly DependencyProperty ImageSourceProperty =
- DependencyProperty.Register("ImageSource", typeof(string), typeof(MyButton), new PropertyMetadata(""));
- public static readonly DependencyProperty ImageSourceChangeProperty =
- DependencyProperty.Register("ImageSourceChange", typeof(string), typeof(MyButton), new PropertyMetadata(""));
- /// <summary>
- /// Static Constructor
- /// </summary>
- static MyButton()
- {
- DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
- IsContextMenuOpenProperty = DependencyProperty.Register("IsContextMenuOpen", typeof(bool), typeof(MyButton), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsContextMenuOpenChanged)));
- ModeProperty = DependencyProperty.Register("Mode", typeof(MyButtonMode), typeof(MyButton), new FrameworkPropertyMetadata(MyButtonMode.Split));
- PlacementProperty = ContextMenuService.PlacementProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(PlacementMode.Bottom, new PropertyChangedCallback(OnPlacementChanged)));
- PlacementRectangleProperty = ContextMenuService.PlacementRectangleProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(Rect.Empty, new PropertyChangedCallback(OnPlacementRectangleChanged)));
- HorizontalOffsetProperty = ContextMenuService.HorizontalOffsetProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(0.0, new PropertyChangedCallback(OnHorizontalOffsetChanged)));
- VerticalOffsetProperty = ContextMenuService.VerticalOffsetProperty.AddOwner(typeof(MyButton), new FrameworkPropertyMetadata(0.0, new PropertyChangedCallback(OnVerticalOffsetChanged)));
- }
- /*
- * Overrides
- *
- */
- /// <summary>
- /// OnApplyTemplate override, set up the click event for the dropdown if present in the template
- /// </summary>
- public override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
- // set up the click event handler for the dropdown button
- System.Windows.Controls.Primitives.ButtonBase dropDown = this.Template.FindName("PART_DropDown", this) as System.Windows.Controls.Primitives.ButtonBase;
- if (dropDown != null)
- dropDown.Click += Dropdown_Click;
- }
- /// <summary>
- /// Handles the Base Buttons OnClick event
- /// </summary>
- protected override void OnClick()
- {
- switch (Mode)
- {
- case MyButtonMode.Dropdown:
- OnDropdown();
- break;
- default:
- base.OnClick(); // forward on the Click event to the user
- break;
- }
- }
- /*
- * Properties
- *
- */
- /// <summary>
- /// The Split Button's Items property maps to the base classes ContextMenu.Items property
- /// </summary>
- public ItemCollection Items
- {
- get
- {
- EnsureContextMenuIsValid();
- return this.ContextMenu.Items;
- }
- }
- /*
- * DependencyProperty CLR wrappers
- *
- */
- public string ImageSource
- {
- get { return (string)GetValue(ImageSourceProperty); }
- set { SetValue(ImageSourceProperty, value); }
- }
- public string ImageSourceChange
- {
- get { return (string)GetValue(ImageSourceChangeProperty); }
- set { SetValue(ImageSourceChangeProperty, value); }
- }
- /// <summary>
- /// Gets or sets the IsContextMenuOpen property.
- /// </summary>
- public bool IsContextMenuOpen
- {
- get { return (bool)GetValue(IsContextMenuOpenProperty); }
- set { SetValue(IsContextMenuOpenProperty, value); }
- }
- /// <summary>
- /// Placement of the Context menu
- /// </summary>
- public PlacementMode Placement
- {
- get { return (PlacementMode)GetValue(PlacementProperty); }
- set { SetValue(PlacementProperty, value); }
- }
- /// <summary>
- /// PlacementRectangle of the Context menu
- /// </summary>
- public Rect PlacementRectangle
- {
- get { return (Rect)GetValue(PlacementRectangleProperty); }
- set { SetValue(PlacementRectangleProperty, value); }
- }
- /// <summary>
- /// HorizontalOffset of the Context menu
- /// </summary>
- public double HorizontalOffset
- {
- get { return (double)GetValue(HorizontalOffsetProperty); }
- set { SetValue(HorizontalOffsetProperty, value); }
- }
- /// <summary>
- /// VerticalOffset of the Context menu
- /// </summary>
- public double VerticalOffset
- {
- get { return (double)GetValue(VerticalOffsetProperty); }
- set { SetValue(VerticalOffsetProperty, value); }
- }
- /// <summary>
- /// Defines the Mode of operation of the Button
- /// </summary>
- /// <remarks>
- /// The MyButton two Modes are
- /// Split (default), - the button has two parts, a normal button and a dropdown which exposes the ContextMenu
- /// Dropdown - the button acts like a combobox, clicking anywhere on the button opens the Context Menu
- /// </remarks>
- public MyButtonMode Mode
- {
- get { return (MyButtonMode)GetValue(ModeProperty); }
- set { SetValue(ModeProperty, value); }
- }
- /*
- * DependencyPropertyChanged callbacks
- *
- */
- private static void OnIsContextMenuOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- MyButton s = (MyButton)d;
- s.EnsureContextMenuIsValid();
- if (!s.ContextMenu.HasItems)
- return;
- bool value = (bool)e.NewValue;
- if (value && !s.ContextMenu.IsOpen)
- s.ContextMenu.IsOpen = true;
- else if (!value && s.ContextMenu.IsOpen)
- s.ContextMenu.IsOpen = false;
- }
- /// <summary>
- /// Placement Property changed callback, pass the value through to the buttons context menu
- /// </summary>
- private static void OnPlacementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- MyButton s = d as MyButton;
- if (s == null) return;
- s.EnsureContextMenuIsValid();
- s.ContextMenu.Placement = (PlacementMode)e.NewValue;
- }
- /// <summary>
- /// PlacementRectangle Property changed callback, pass the value through to the buttons context menu
- /// </summary>
- private static void OnPlacementRectangleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- MyButton s = d as MyButton;
- if (s == null) return;
- s.EnsureContextMenuIsValid();
- s.ContextMenu.PlacementRectangle = (Rect)e.NewValue;
- }
- /// <summary>
- /// HorizontalOffset Property changed callback, pass the value through to the buttons context menu
- /// </summary>
- private static void OnHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- MyButton s = d as MyButton;
- if (s == null) return;
- s.EnsureContextMenuIsValid();
- s.ContextMenu.HorizontalOffset = (double)e.NewValue;
- }
- /// <summary>
- /// VerticalOffset Property changed callback, pass the value through to the buttons context menu
- /// </summary>
- private static void OnVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- MyButton s = d as MyButton;
- if (s == null) return;
- s.EnsureContextMenuIsValid();
- s.ContextMenu.VerticalOffset = (double)e.NewValue;
- }
- /*
- * Helper Methods
- *
- */
- /// <summary>
- /// Make sure the Context menu is not null
- /// </summary>
- private void EnsureContextMenuIsValid()
- {
- if (this.ContextMenu == null)
- {
- this.ContextMenu = new System.Windows.Controls.ContextMenu();
- this.ContextMenu.PlacementTarget = this;
- this.ContextMenu.Placement = Placement;
- this.ContextMenu.Opened += ((sender, routedEventArgs) => IsContextMenuOpen = true);
- this.ContextMenu.Closed += ((sender, routedEventArgs) => IsContextMenuOpen = false);
- }
- }
- private void OnDropdown()
- {
- EnsureContextMenuIsValid();
- if (!this.ContextMenu.HasItems)
- return;
- this.ContextMenu.IsOpen = !IsContextMenuOpen; // open it if closed, close it if open
- }
- /*
- * Events
- *
- */
- /// <summary>
- /// Event Handler for the Drop Down Button's Click event
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Dropdown_Click(object sender, RoutedEventArgs e)
- {
- OnDropdown();
- e.Handled = true;
- }
- }
- }
控件xaml
- <ResourceDictionary
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:comm="clr-namespace:Controls">
- <Style x:Key="ButtonFocusVisual">
- <Setter Property="Control.Template">
- <Setter.Value>
- <ControlTemplate>
- <Rectangle
- Margin=""
- SnapsToDevicePixels="true"
- Stroke="Transparent"
- StrokeDashArray="1 2"
- StrokeThickness="" />
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- <Style TargetType="Button">
- <Setter Property="Foreground" Value="#D5D5D5" />
- <Setter Property="FontSize" Value="" />
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="Button">
- <Image
- x:Name="image"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Source="{Binding Path=ImageSource, RelativeSource={RelativeSource AncestorType={x:Type comm:MyButton}}}" />
- <ControlTemplate.Triggers>
- <Trigger Property="IsMouseOver" Value="True">
- <Setter TargetName="image" Property="Source" Value="{Binding Path=ImageSourceChange, RelativeSource={RelativeSource AncestorType={x:Type comm:MyButton}}}" />
- </Trigger>
- </ControlTemplate.Triggers>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- <Style TargetType="{x:Type comm:MyButton}">
- <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}" />
- <Setter Property="FontSize" Value="" />
- <Setter Property="Foreground" Value="#D5D5D5" />
- <Setter Property="FontFamily" Value="微软雅黑" />
- <Setter Property="HorizontalContentAlignment" Value="Center" />
- <Setter Property="VerticalContentAlignment" Value="Center" />
- <Setter Property="Padding" Value="" />
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="{x:Type comm:MyButton}">
- <Border
- x:Name="grid"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Background="Transparent"
- CornerRadius="">
- <Button x:Name="PART_DropDown" />
- </Border>
- <ControlTemplate.Triggers>
- <Trigger SourceName="PART_DropDown" Property="IsMouseOver" Value="true">
- <Setter TargetName="PART_DropDown" Property="Opacity" Value="" />
- <Setter TargetName="grid" Property="Background" Value="Transparent" />
- </Trigger>
- <Trigger Property="IsEnabled" Value="false">
- <Setter Property="Foreground" Value="#ADADAD" />
- </Trigger>
- </ControlTemplate.Triggers>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- </ResourceDictionary>
页面使用:
- <comm:MyButton
- Width=""
- Height=""
- ImageSource="/control;component/Icons/picture2.png"
- ImageSourceChange="/control;component/Icons/picture1.png">
- </comm:MyButton>
WPF自定义控件 依赖属性绑定的更多相关文章
- WPF自定义控件的自定义属性绑定后不更新问题
原文:WPF自定义控件的自定义属性绑定后不更新问题 需要在绑定时设置属性变更触发 UpdateSourceTrigger=PropertyChanged 例如: <Border CornerRa ...
- WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性
原文:WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性 如果你要自定义一个图片按钮控件,那么如何在主窗体绑定这个控件上图片的Source呢? ...
- WPF的依赖属性和附加属性(用法解释较全)
转:https://www.cnblogs.com/zhili/p/WPFDependencyProperty.html 一.引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己 ...
- WPF的依赖属性
Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR)属性的功能,这些服务通常统称为 WPF 属性系统.由 WPF 属 ...
- wpf 的依赖属性只能在loaded 事件之后才能取到
wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的 InitializeComponent(); 之后取不到 wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的 ...
- WPF 中依赖属性的继承(Inherits)
WPF中依赖属性的值是是可以设置为可继承(Inherits)的,这种模式下,父节点的依赖属性会将其值传递给子节点.例如,数据绑定中经常使用的DataContextProperty: var host ...
- WPF利用依赖属性和命令编写自定义控件
以实例讲解(大部分讲解在代码中) 1,新建一个WPF项目,添加一个用户控件之后在用户控件里面添加几个控件用作测试, <UserControl x:Class="SelfControlD ...
- WPF 使用依赖属性自定义控件
使用依赖属性自定义控件,依赖属性必须定义在自定义控件中,不能定义在其他文件中 一.先实现一个类继承你要复写的类 using System; using System.Collections.Gener ...
- WPF: 只读依赖属性的介绍与实践
在设计与开发 WPF 自定义控件时,我们常常为会控件添加一些依赖属性以便于绑定或动画等.事实上,除了能够添加正常的依赖属性外,我们还可以为控件添加只读依赖属性(以下统称"只读属性" ...
随机推荐
- centos7下python3和pycharm安装
1.python3安装 直接到官网下载或在以下地址下载让后解压安装 下载地址:https://www.python.org/ftp/python/ 安装参考博客:https://www.cnblogs ...
- storm运行服务器一些错误解决、
java.lang.RuntimeException: Returned channel was actually not established 重启试试 Java.lang.NoSuchMetho ...
- Idea SSH框架整合基础代码
第一步 pom.xml注入jar包依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" ...
- 2019-8-30-BAT-脚本判断当前系统是-x86-还是-x64-系统
title author date CreateTime categories BAT 脚本判断当前系统是 x86 还是 x64 系统 lindexi 2019-08-30 08:47:40 +080 ...
- react-native start停止在Loading dependency graph, done.
在试验的过程中. 发现运行 react-native start会卡住,停留在Loading dependency graph, done. 原因大概是之前运行过 react-native run-a ...
- LA4670 Dominating Patterns AC自动机模板
Dominating Patterns 每次看着别人的代码改成自己的模板都很头大...空间少了个0卡了好久 裸题,用比map + string更高效的vector代替蓝书中的处理方法 #include ...
- 国内在Amazon fireTV或者fire平板下载应用(netflix\hulu\YouTube)的方法
1.首先需要vpn翻墙至U.S. 2.需要一个美国亚马逊账户,并设置收货地址 (Manage Your Fire & Kindle 1-Click Payment Settings ),如果只 ...
- Ubuntu下使用sshfs挂载远程目录到本地
访问局域网中其他Ubuntu机器,在不同机器间跳来跳去,很是麻烦,如果能够把远程目录映射到本地无疑会大大方面使用,就像Windows下的网络映射盘一样.在Linux的世界无疑也会有这种机制和方式,最近 ...
- echarts--例子
echarts使用例子: <script type="text/javascript"> option = { title : {'x': 'center','y':' ...
- 让footer始终待在页面底部
1.把html和body的height属性设为100%;保证content的高度能撑满浏览器; 2.把#content的高度也设置为100% ,但是这里我们使用了“min-height”属性,而不是的 ...