[WPF系列]-DataBinding(数据绑定) 自定义Binding
自定义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的更多相关文章
- WPF QuickStart系列之数据绑定(Data Binding)
这篇博客将展示WPF DataBinding的内容. 首先看一下WPF Data Binding的概览, Binding Source可以是任意的CLR对象,或者XML文件等,Binding Targ ...
- WPF中的数据绑定Data Binding使用小结
完整的数据绑定的语法说明可以在这里查看: http://www.nbdtech.com/Free/WpfBinding.pdf MSDN资料: Data Binding: Part 1 http:// ...
- [WPF系列]-DataBinding 绑定计算表达式
Width="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth, Converter={Stat ...
- [WPF系列]-DataBinding 枚举类型数据源
public class EnumerationDataProvider : ObjectDataProvider { public Type EnumerationType { get; set; ...
- WPF学习09:数据绑定之 Binding to List Data
从WPF学习03:Element Binding我们可以实现控件属性与控件属性的绑定. 从WPF学习07:MVVM 预备知识之数据绑定 我们可以实现控件属性与自定义对象属性的绑定. 而以上两个功能在实 ...
- WPF编游戏系列 之五 数据绑定
原文:WPF编游戏系列 之五 数据绑定 在上一篇通过用户控件将重复使用的控件封装为一个控件组,大大减少了C#代码数量,本篇继续对该控件组进行数据绑定,节省为每个控件赋值的工作.对于数据绑 ...
- WPF入门教程系列十五——WPF中的数据绑定(一)
使用Windows Presentation Foundation (WPF) 可以很方便的设计出强大的用户界面,同时 WPF提供了数据绑定功能.WPF的数据绑定跟Winform与ASP.NET中的数 ...
- WPF之数据绑定Data Binding
一般情况下,应用程序会有三层结构:数据存储层,数据处理层(业务逻辑层),数据展示层(UI界面). WPF是“数据驱动UI”. Binding实现(通过纯C#代码) Binding分为source和ta ...
- [WPF系列]-TreeView的常用事项
引言 项目经常会用Treeview来组织一些具有层级结构的数据,本节就将项目使用Treeview常见的问题作一个总结. DataBinding数据绑定 DataTemplate自定义 <Hier ...
随机推荐
- FreeRTOS 中断优先级嵌套错误引发HardFault异常解决(转)
最近在使用FreeRTOS的时候,突然发现程序在运行了几分钟之后所有的任务都不再调用了,只有几个中断能正常使用,看来是系统挂掉了,连续测试了几次想找出问题,可是这个真的有点不知所措. 我 ...
- C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现之方法二:加入缓存机制
在上一篇文章中我用递归方法实现了管理菜单,在上一节我也提到要考虑用缓存,也算是学习一下.Net Core的缓存机制. 关于.Net Core的缓存,官方有三种实现: 1.In Memory Cachi ...
- 【手记】未能从程序集System.Net.Http.Formatting中加载类型System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter
实际报错如图: 如果你跟我一样是在折腾Asp.Net WebApi 2.x时遇到这个问题,请参看如下办法: 删除现有System.Net.Http.Formatting引用(如果引用了的话) 重新引用 ...
- WinServer远程部署系统(RDSystem)
系统简介 RemoteDeploySystem是一套BS结构的远程部署管理系统(简称RDSystem),可以通过浏览器上传web站点和windows服务的更新包到RDSystem服务器,然后对多个服务 ...
- HTTP协议详解
Author :Jeffrey 引言 HTTP 是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和 扩展. ...
- 突如其来的"中断异常",我(Java)该如何处理?
一.何为异常? 1.生活中的实例 生活中存在许多不正常: 上班路上自行车掉链子 上厕所手机掉马桶 下班回家钥匙丢失 ....... 2.程序中的实例 我们的代码中也许存在许多纰漏,导致用户使用时程序突 ...
- 15、ASP.NET MVC入门到精通——MVC-路由
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 Routing(路由) – URL url 作为广泛使用的Web用户接口,需要被重视 好的Url应该满足如下条件: URL应为获取某种资源提 ...
- js中constructor和prototype
在最开始学习js的时候,我们在讲到原型链和构造函数的时候经常会有一个例子 如果我们定义函数如下: function Foo() { /* .. */ } Foo.prototype.bar = fun ...
- View and Data API tips: 缓存Access Token
对于云API服务,常见的方式就是按照API调用次数收费,某些API调用也就有某些限制,比如在特定时间内只允许调用指定的次数以免造成滥用.虽然Autodesk的view and Data API目前还没 ...
- statusbarhidden stuff 状态栏的各种特性
plist 文件中的View controller-based status bar appearance 设置的是 在viewcontroller 中 对状态栏进行修改是否起作用. 设置状态栏隐藏和 ...