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 自定义控件时,我们常常为会控件添加一些依赖属性以便于绑定或动画等.事实上,除了能够添加正常的依赖属性外,我们还可以为控件添加只读依赖属性(以下统称"只读属性" ...
随机推荐
- jeecms 修改后台访问路径
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_30553235/article/details/74971414 我使用的是jeecms ...
- OpenCASCADE动画功能
OpenCASCADE动画功能 eryar@163.com 1.Introduction OpenCASCADE提供了类AIS_Animation等来实现简单的动画功能. 从其类图可以看出,动画功能有 ...
- VS C++/ClI调用C++ 外部Dll无法查看变量值
C#项目调用C++/ClI项目,C++/ClI项目又引用了外部C++ dll时 C++/CLI代码中在调试时无法查看native 变量的值 解决方法:C#项目右键属性-->Debug--> ...
- IO流18 --- RandomAccessFile实现数据的读写操作 --- 技术搬运工(尚硅谷)
RandomAccessFile实例化时,需要设置读写模式 示例:复制文件 @Test public void test16() throws IOException { RandomAccessFi ...
- VMWare下载安装以及创建虚拟机教程
参考博客https://blog.csdn.net/qq_39135287/article/details/83993574 下载 1.打开官网https://www.vmware.com/cn.ht ...
- 同一浏览器中同一JavaWeb程序不共享session方法
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/b2084005/article/details/302227351.要求 在使用struts1开发J ...
- Django项目:CRM(客户关系管理系统)--24--16PerfectCRM实现King_admin日期过滤
登陆密码设置参考 http://www.cnblogs.com/ujq3/p/8553784.html list_filter = ('date','source','consultant','con ...
- 通过游戏学python 3.6 第一季 第三章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码 可复制直接使用 娱乐 可封装 函数
猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码 #猜数字--核心代码--猜测次数--随机函数和屏蔽错误代码 import random secrst = random.rand ...
- zoj 1001 python起步
/*赶角还是挺好的....*/ import sys for line in sys.stdin: a=line.split() print int(a[0])+int(a[1])
- WPF 从属性赋值到MVVM模式详解
示例源码 这两天学习了一下MVVM模式,和大家分享一下,也作为自己的学习笔记.这里不定义MVVM的概念,不用苍白的文字说它的好处,而是从简单的赋值讲起,一步步建立一个MVVM模式的Simple.通过前 ...