介绍WPF中DependencyProperty的一些基本用法

转自:http://blog.sina.com.cn/s/blog_6130c4c40100e7ud.html
这一篇Post中,我准备先介绍WPF中DependencyProperty的一些基本用法。

在程序中使用DependencyProperty好的,我相信你已经决定了要使用DependencyProperty而不是传统的CLR属性,正如上一篇Post所说,很多地方都需要使用到DependencyProperty,作为例子,我决定定义一个MyBorderEx,在WPF常用的”Border”控件中创建一个名为Transparency的属性,来指示它的透明度,这个属性值在0-255间变化,255表示全透明,0表示完全不透明。
我们首先定义这个DependencyProperty:

public readonly static DependencyProperty TransparencyDependency =
DependencyProperty.Register(
“Transparency”,
typeof(Double),
typeof(MyBorderEx)
);
public Double Transparency
{
get { return (Double)GetValue(TransparencyDependency); }
set { SetValue(TransparencyDependency, value); }
}
这是标准的定义方式,首先定义了一个静态的DependencyProperty变量。然后封装了Transparency属性,这样可以完成向前兼容,MSDN中称为”CLR Wapper”。
我们只是定义了这个属性,不过这个属性更改时还不会自动的去更新MyBorderEx的透明度,其实WPF中包含有一个默认的名为Opacity的属性来完成这个工作,我们就借用他来实现这个功能。也许你会想这么做。

public Double Transparency
{
get { return (Double)GetValue(TransparencyDependency); }
set
{
SetValue(TransparencyDependency, value);
Opacity = 1 - ((double)value / 255);
}
}
如果这是传统的属性,也许我们只有这么做了,但是如果你使用这种做法的话,只有在手动改变”Transparency”的值也就是调用了Set方法时才会更新Border的Opacity属性,但是如果在XAML代码中改变Transparency属性,WPF是不会调用Set方法的,因此这时类似下面的代码会没有效果。


实际上,当你使用类似 Transparency=”50” 这样的语法时,WPF会直接通过”Transparency”字符串,直接寻找到这个DependencyProperty的值(还记得Register的时候我们传了一个”Transparency”过去吗,值就是根据这个字符串找到的),然后更改这个DependencyProperty的值。

一种解决方式如下,DependecyProperty提供了属性改变通知的功能,我们可以利用DependencyProperty的这个功能,定义一个transparencyPropertyChangedCallback函数,在属性值变化(注意,这里指DependencyProperty的值发生变化而不是我们定义的”CLR wapper”的Transparency属性)时修改Opacity属性。我们现在先这样做,后面的Post中我会使用更漂亮(正统)的方式解决这个问题,完整代码如下:

class MyBorderEx:Border
{
public MyBorderEx()
{
//初始化时默认给定一个背景色
Background = Brushes.Blue;
}
public readonly static DependencyProperty TransparencyDependency =
DependencyProperty.Register(
“Transparency”,
typeof(Double),
typeof(MyBorderEx),
new PropertyMetadata(new PropertyChangedCallback(transparencyPropertyChangedCallback))
);

static void transparencyPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
MyBorderEx border = (sender as MyBorderEx);
if (border != null)
{
border.Opacity =1 - Convert.ToDouble(e.NewValue) / 255;
}
}

public Double Transparency
{
get { return (Double)GetValue(TransparencyDependency); }
set { SetValue(TransparencyDependency, value); }
}
}

主窗体中的XAML调用代码:


很有意思的是,XAML中改变属性的值,并又不是通过Transparency属性的set方法,你可以在Transparency的set方法中设置断点或写一些其他代码,这些代码并不会被执行。但是,这里你并不能删除看似没什么用处的Transparency属性,也就是所谓的”CLR Wapper”,甚至你不能删除这个不会被执行到的set方法。否则XAML调用中会报错。

为了证明以上结论,你可以试着把set方法中的那行SetValue(TransparencyDependency, value); 去掉,程序依然正常运行。但是如果你移除了整条set方法,编译会不通过。

好,我们把代码还原,这样已经就完成了一个DependencyProperty的定义,下面我们给这个小程序加上两个功能。

前面提到过,使用了DependencyProperty的属性可以用作数据绑定目标,我们在Window上放一个Slider测试一下数据绑定效果。目标:使用Slider动态改变Border的透明度,我全部使用XAML实现,只有很简单的两行代码


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF,可以使用ShaderEffect来设置ImageBrush的亮度。具体步骤如下: 1. 创建一个自定义的ShaderEffect类,继承自System.Windows.Media.Effects.ShaderEffect。 2. 在类添加一个DependencyProperty,用于传递亮度值。 3. 重写CreateShader()方法,在其加载HLSL文件,并将亮度值传递给Shader。 4. 在XAML使用Rectangle控件,并将自定义的ShaderEffect作为Fill属性的值,同时将Rectangle的Width和Height设置为ImageBrush的宽度和高度。 5. 在Rectangle的RenderTransform属性添加一个ScaleTransform,用于设置Rectangle的缩放比例,以保证图片在Rectangle完整显示。 下面是一个简单的实现示例: ```csharp public class BrightnessEffect : ShaderEffect { private static PixelShader _pixelShader = new PixelShader(); static BrightnessEffect() { _pixelShader.UriSource = new Uri("BrightnessEffect.ps", UriKind.Relative); } public BrightnessEffect() { this.PixelShader = _pixelShader; UpdateShaderValue(BrightnessProperty); } public static readonly DependencyProperty BrightnessProperty = DependencyProperty.Register("Brightness", typeof(double), typeof(BrightnessEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(0))); public double Brightness { get { return (double)GetValue(BrightnessProperty); } set { SetValue(BrightnessProperty, value); } } } ``` 其,BrightnessEffect.ps是一个HLSL文件,用于实现亮度调节的Shader代码。 使用时,可以将该类作为Rectangle控件的Fill属性的值,并将Rectangle的Width和Height设置为ImageBrush的宽度和高度: ```xml <Rectangle Width="100" Height="100"> <Rectangle.Fill> <ImageBrush ImageSource="test.png"> <ImageBrush.Effect> <local: BrightnessEffect Brightness="0.5"/> </ImageBrush.Effect> </ImageBrush> </Rectangle.Fill> <Rectangle.RenderTransform> <ScaleTransform ScaleX="1" ScaleY="-1"/> </Rectangle.RenderTransform> </Rectangle> ``` 在这个例子,将Brightness属性设置为0.5,表示将图片的亮度调高50%。同时,为了保证图片在Rectangle完整显示,还添加了一个ScaleTransform,将Rectangle沿Y轴翻转。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值