自定义Binding

A base class for custom WPF binding markup extensions

BindingDecoratorBase

Code:

public class LookupExtension : BindingDecoratorBase
{
//A property that can be set in XAML
public string LookupKey { get; set; } public override object ProvideValue(IServiceProvider provider)
{
//delegate binding creation etc. to the base class
object val = base.ProvideValue(provider); //try to get bound items for our custom work
DependencyObject targetObject;
DependencyProperty targetProperty;
bool status = TryGetTargetItems(provider, out targetObject,
out targetProperty); if (status)
{
//associate an input listener with the control
InputHandler.RegisterHandler(targetObject, LookupKey);
} return val;
}
}

 

XAML:

<TextBox Name="txtZipCode">
<TextBox.Text>
<local:LookupExtension Source="{StaticResource MyAddress}"
Path="ZipCode"
LookupKey="F5" />
</TextBox.Text>
</TextBox>

效果图:

---------------------------------------------===================================------------------------------

DelayBinding: a custom WPF Binding

 

 

<TextBox Text="{z:DelayBinding Path=SearchText, Delay='00:00:01'}" />

 

[MarkupExtensionReturnType(typeof(object))]
public class DelayBindingExtension : MarkupExtension
{
public DelayBindingExtension()
{
Delay = TimeSpan.FromSeconds(0.5);
} public DelayBindingExtension(PropertyPath path)
: this()
{
Path = path;
} public IValueConverter Converter { get; set; }
public object ConverterParamter { get; set; }
public string ElementName { get; set; }
public RelativeSource RelativeSource { get; set; }
public object Source { get; set; }
public bool ValidatesOnDataErrors { get; set; }
public bool ValidatesOnExceptions { get; set; }
public TimeSpan Delay { get; set; }
[ConstructorArgument("path")]
public PropertyPath Path { get; set; }
[TypeConverter(typeof(CultureInfoIetfLanguageTagConverter))]
public CultureInfo ConverterCulture { get; set; } public override object ProvideValue(IServiceProvider serviceProvider)
{
var valueProvider = serviceProvider.GetService(typeof (IProvideValueTarget)) as IProvideValueTarget;
if (valueProvider != null)
{
var bindingTarget = valueProvider.TargetObject as DependencyObject;
var bindingProperty = valueProvider.TargetProperty as DependencyProperty;
if (bindingProperty == null || bindingTarget == null)
{
throw new NotSupportedException(string.Format(
"The property '{0}' on target '{1}' is not valid for a DelayBinding. The DelayBinding target must be a DependencyObject, "
+ "and the target property must be a DependencyProperty.",
valueProvider.TargetProperty,
valueProvider.TargetObject));
} var binding = new Binding();
binding.Path = Path;
binding.Converter = Converter;
binding.ConverterCulture = ConverterCulture;
binding.ConverterParameter = ConverterParamter;
if (ElementName != null) binding.ElementName = ElementName;
if (RelativeSource != null) binding.RelativeSource = RelativeSource;
if (Source != null) binding.Source = Source;
binding.ValidatesOnDataErrors = ValidatesOnDataErrors;
binding.ValidatesOnExceptions = ValidatesOnExceptions; return DelayBinding.SetBinding(bindingTarget, bindingProperty, Delay, binding);
}
return null;
}
}
public class DelayBinding
{
private readonly BindingExpressionBase _bindingExpression;
private readonly DispatcherTimer _timer; protected DelayBinding(BindingExpressionBase bindingExpression, DependencyObject bindingTarget, DependencyProperty bindingTargetProperty, TimeSpan delay)
{
_bindingExpression = bindingExpression; // Subscribe to notifications for when the target property changes. This event handler will be
// invoked when the user types, clicks, or anything else which changes the target property
var descriptor = DependencyPropertyDescriptor.FromProperty(bindingTargetProperty, bindingTarget.GetType());
descriptor.AddValueChanged(bindingTarget, BindingTarget_TargetPropertyChanged); // Add support so that the Enter key causes an immediate commit
var frameworkElement = bindingTarget as FrameworkElement;
if (frameworkElement != null)
{
frameworkElement.KeyUp += BindingTarget_KeyUp;
} // Setup the timer, but it won't be started until changes are detected
_timer = new DispatcherTimer();
_timer.Tick += Timer_Tick;
_timer.Interval = delay;
} private void BindingTarget_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key != Key.Enter) return;
_timer.Stop();
_bindingExpression.UpdateSource();
} private void BindingTarget_TargetPropertyChanged(object sender, EventArgs e)
{
_timer.Stop();
_timer.Start();
} private void Timer_Tick(object sender, EventArgs e)
{
_timer.Stop();
_bindingExpression.UpdateSource();
} public static object SetBinding(DependencyObject bindingTarget, DependencyProperty bindingTargetProperty, TimeSpan delay, Binding binding)
{
// Override some specific settings to enable the behavior of delay binding
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit; // Apply and evaluate the binding
var bindingExpression = BindingOperations.SetBinding(bindingTarget, bindingTargetProperty, binding); // Setup the delay timer around the binding. This object will live as long as the target element lives, since it subscribes to the changing event,
// and will be garbage collected as soon as the element isn't required (e.g., when it's Window closes) and the timer has stopped.
new DelayBinding(bindingExpression, bindingTarget, bindingTargetProperty, delay); // Return the current value of the binding (since it will have been evaluated because of the binding above)
return bindingTarget.GetValue(bindingTargetProperty);
}
}

 

参考

Automatically validating business entities in WPF using custom binding and attributes

Flexible and Powerful Data Binding with WPF, Part 2

[WPF系列]-DataBinding(数据绑定) 自定义Binding的更多相关文章

  1. WPF QuickStart系列之数据绑定(Data Binding)

    这篇博客将展示WPF DataBinding的内容. 首先看一下WPF Data Binding的概览, Binding Source可以是任意的CLR对象,或者XML文件等,Binding Targ ...

  2. WPF中的数据绑定Data Binding使用小结

    完整的数据绑定的语法说明可以在这里查看: http://www.nbdtech.com/Free/WpfBinding.pdf MSDN资料: Data Binding: Part 1 http:// ...

  3. [WPF系列]-DataBinding 绑定计算表达式

            Width="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth, Converter={Stat ...

  4. [WPF系列]-DataBinding 枚举类型数据源

    public class EnumerationDataProvider : ObjectDataProvider { public Type EnumerationType { get; set; ...

  5. WPF学习09:数据绑定之 Binding to List Data

    从WPF学习03:Element Binding我们可以实现控件属性与控件属性的绑定. 从WPF学习07:MVVM 预备知识之数据绑定 我们可以实现控件属性与自定义对象属性的绑定. 而以上两个功能在实 ...

  6. WPF编游戏系列 之五 数据绑定

    原文:WPF编游戏系列 之五 数据绑定        在上一篇通过用户控件将重复使用的控件封装为一个控件组,大大减少了C#代码数量,本篇继续对该控件组进行数据绑定,节省为每个控件赋值的工作.对于数据绑 ...

  7. WPF入门教程系列十五——WPF中的数据绑定(一)

    使用Windows Presentation Foundation (WPF) 可以很方便的设计出强大的用户界面,同时 WPF提供了数据绑定功能.WPF的数据绑定跟Winform与ASP.NET中的数 ...

  8. WPF之数据绑定Data Binding

    一般情况下,应用程序会有三层结构:数据存储层,数据处理层(业务逻辑层),数据展示层(UI界面). WPF是“数据驱动UI”. Binding实现(通过纯C#代码) Binding分为source和ta ...

  9. [WPF系列]-TreeView的常用事项

    引言 项目经常会用Treeview来组织一些具有层级结构的数据,本节就将项目使用Treeview常见的问题作一个总结. DataBinding数据绑定 DataTemplate自定义 <Hier ...

随机推荐

  1. 关系数据库SQL之可编程性函数(用户自定义函数)

    前言 在关系型数据库中除了前面几篇基本的数据库和数据表操作之外,还提供了可编程性的函数.存储过程.事务.触发器及游标. 本文介绍的是函数. 函数分为两种: 系统函数 用户自定义函数 准备工作 这里以银 ...

  2. 怎么搭建EF的环境?(Entity Framework)

    1.EF是什么? EF是.net封装的一个用于数据库交互的实体层框架,它的全称是Entity Framework. 2.EF搭建: 新建之后,我们就可以看到里面的内容: 我们可以分别看一下它里面有些什 ...

  3. python基础学习笔记2

    词典   词典(dictionary)与列表相似,也可以存储多个元素.存储多个元素的对象称为容器(container); 常见的创建词典的方法: >>>dic = {'tom':11 ...

  4. CSS实现弹出导航菜单

    查看实际效果:http://keleyi.com/a/bjac/vksd7321.htm 完整代码,保存在html文件打开也可看到效果: <!DOCTYPE html PUBLIC " ...

  5. jquery点击复选框触发事件给input赋值

    体验效果:http://keleyi.com/keleyi/phtml/jqtexiao/31.htm 代码如下: <!DOCTYPE html> <html xmlns=" ...

  6. 又到周末了,我们一起来研究【浏览器如何检测是否安装app】吧

    前言 扯淡 这个月比较倒霉,我送了女朋友一台笔记本电脑作为生日礼物,结果15天一过电脑就坏了,悲剧的我还把电脑盒子给扔了!淘宝不给换更不给退 于是被女朋友臭骂了一过星期后,今天本来在公司有任务的,但是 ...

  7. jquery-懒加载技术(简称lazyload)

    第一:lazyLoad简介及作用 网站性能优化的插件,提高用户体验. 页面如果有很多图片的时候,当你滚动到相应的行时,当前行的图片才即时加载的,这样子的话页面在打开只加可视区域的图片,而其它隐藏的图片 ...

  8. 解决JqueryUI 拖放排序遇到滚动条时有可能无法执行排序的小bug

    前些日子不是在做 使用Jquery-UI实现一次拖拽多个选中的元素操作嘛,在持续完善这个组件时遇到了一个关于拖放排序的bug.今天就着图片和代码重现一下,也顺便告诉大家如何解决这个问题. 首先先上图描 ...

  9. 函数模块:CTVB_COMPARE_TABLES--两个表中删除/变更/粘贴分解

    这个函数模块比较两个内表,将被删除.增加和修改的内表行分别分组输出. 输入参数:TABLE_OLD:旧表TABLE_NEW:新表KEY_LENGTH:键长度,指定内表中的前若干个字节(在 Unicod ...

  10. Atitit. 查找linux 项目源码位置

    Atitit. 查找linux 项目源码位置 1. netstat   -anp |grep 801 1.1. 1.3 启动关闭nginx3 1.2. 找到nginx配置文件4 1.3. ./etc/ ...