WPF Data Binding之控件作为源(Source)与路径(Path)【二】

    Binding 的源也就是数据的源头。Binding对源的要求并不苛刻------只要它是一个对象,并且通过属性(Property)公开自己的数据,它就能作为Binding 的源。

    前面一个例子已经向大家证明,如果想让作为Binding源的对象具有自动通知Binding自己属性值已经已经变化的能力,那么就需要让类实现INotifyChanged接口并在属性的Set语句中激发PropertyChanged事件。在日常生活中,除了使用这种对象作为数据源之外,我们还有更多的选择,比如用一个控件做为另一个控件的数据源,把集合作为ItemControl的数据源、使用XML作为TreeView或Menu的数据源等。

1. 把控件作为Binding源

    大多数情况下Binding的源是逻辑层对象,但有的时候为了让UI产生联动效果也会使用Binding在控件间建立关联。
    Binding在源与目标之间架起了沟通的桥梁,默认情况下数据即可以通过Binding送达目标,也可以通过目标回到源(收集用户对数据的修改)。有时候数据只需要展示给用户,不需要用户修改,这时候可以把Binding模式设置为从目标向源的单向沟通以及只在Binding关系确立时读取一次数据,这需要我们根据实际情况选择。

    控制Binding数据流向的属性是Model,它的类型是BindingModel的枚举。BindingModel可以取值为TwoWay、OneWay、OneTime、OneWayToSource和Default。这里的Default指的是Binding的模式会根据目标是实际情况来确定,如是可以编辑的(TextBox的Text属性),Default就采用双向模式。如果是TextBlock,不可编辑,就使用单向模式。

    拖动Slider手柄时,TextBox就会显示Slider的当前值(实际上这一块涉及到一个Double到String类型的转换,暂且忽略不计);如果我们在TextBox里面输入一个恰当的值按Tab键、让焦点离开TextBox,则Slider手柄就会跳转至相应的值那里。为什么一定要在TextBox失去焦点以后才改变值呢?这就引出了Binding的另外一个属性----- UpdateSourceTrigger ,它的类型是UpdateSourceTrigger枚举,可取值为PropertyChanged、LostFous、Explicit和Default。显然,对于Text的Default行为与LostFocus一致,我们只需要把这个值改成PropertyChanged,则Slider就会随着输入值的变化而变化了。
下面的代码是吧一个TextBox的Text属性关联到Slider的Value的属性上。
XAML:
<Window x:Class="WpfApplication6.wnd631"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="wnd631" Height="110" Width="300">
    <StackPanel>
        <TextBox x:Name="_txtBox" BorderBrush="Black" Margin="5"/>
        <Slider x:Name="_slider" Margin="5" Maximum="100"/>
    </StackPanel>
</Window>

C#:
_txtBox.SetBinding(TextBox.TextProperty, new Binding("Value") {
    Source = _slider, 
    Mode = BindingMode.OneWay,  // 更新的方向
    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged // 更新的时机
});


注意:
顺便提一句,Binding还具有NotifyOnSourceUpdated属性和NotifyOnTargetUpdated两个bool类型是属性。如果设置为True,则在源或目标被更新以后就会触发相应的SourceUpdated事件和TargetUpdated事件。实际工作中我们可以监听这两个事件来找出来哪些数据或控件被更新了。

2. Binding的路径(Path)

    作为Binding的源可能会有很多属性,通过这些属性Binding源可以把数据暴露给外界。那么,Binding到底需要关注哪个属性值呢?就需要用Binding的Path属性来指定了。例如前面这个例子,我们把Slider控件对象作为数据源,把它的Value属性作为路径。
尽管在XAML代码中或者Binding类的构造器参数列表中我们使用字符串来表示Path,但Path的实际类型是PropertyPath。

2.1 支持多级路径

    Binding还支持多级路径(通俗的讲就是一路“点”下去),比如,我们想让一个TextBox显示另外一个TextBox内容的长度,我们可以这样写:
// 使用文本的长度作为Path
_txtBox2.SetBinding(TextBox.TextProperty, new Binding("Text.Length")
{
    Source = _txtBox1,
    Mode = BindingMode.OneWay
});

2.2 集合元素的默认元素作为数据源

    集合或者DataView做为数据源时,如果我们想把它默认的元素做为数据源使用,则需要使用下面的语法:
// 集合元素的默认元素当作Path
List<string> strList = new List<string>() { "Tim", "lkjh" };
_txtBox3.SetBinding(TextBox.TextProperty, new Binding("/") 
{
    Source = strList,
    Mode = BindingMode.OneWay    
});

_txtBox4.SetBinding(TextBox.TextProperty, new Binding("/Length")
{
    Source = strList,
    Mode = BindingMode.OneWay    
});

_txtBox5.SetBinding(TextBox.TextProperty, new Binding("/[2]") 
{
    Source = strList,
    Mode = BindingMode.OneWay    
});
 

2.3 "没有Path"的Binding

    有的时候我们会在代码中我们看到Path是一个“.”或者干脆没有Path的Binding,着实让人摸不着头脑。原来这是一种比较特殊的情况---Binding源本身就是一种数据且不需要Path来指明。典型的string,int等基本类型都是这样,他们是实例本身就是数据,我们无法指定通过那个属性来访问这个数据,这是我们只需要将这个数据设置为“.”就可以了。在XAML中这个.可以忽略不写,但是在C#中编程必须要带上。下面请看下面这段代码:
// 没有Path的Source
string myStr = "hfdahfdlh;ahdfhfsahdfhasdfa";
_txtBox6.SetBinding(TextBox.TextProperty, new Binding(".")
{
    Source = myStr,
    Mode = BindingMode.OneWay    
});

完整代码:
XAML:
<Window x:Class="WpfApplication6.wnd633"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="wnd633" Height="400" Width="600">
    <Grid>
        <Label Content="多级路径(一路点下去)" Margin="10,10,358,328"/>
        <TextBox x:Name="_txtBox1" Margin="10,47,358,291" />
        <TextBox x:Name="_txtBox2" Margin="10,121,358,217" />

        <Label Content="集合的默认元素(一路斜下去)" Margin="333,10,35,328"/>
        <TextBox x:Name="_txtBox3" Margin="333,47,35,291" />
        <TextBox x:Name="_txtBox4" Margin="333,84,35,254" />
        <TextBox x:Name="_txtBox5" Margin="333,121,35,217" />

        <Label Content="没有Path的Source" Margin="10,188,358,150"/>
        <TextBox x:Name="_txtBox6" Margin="10,225,358,113" />

    </Grid>
</Window>

C#:
// 使用文本的长度作为Path
_txtBox2.SetBinding(TextBox.TextProperty, new Binding("Text.Length")
{
    Source = _txtBox1,
    Mode = BindingMode.OneWay
});

// 集合元素的默认元素当作Path
List<string> strList = new List<string>() { "Tim", "lkjh" };
_txtBox3.SetBinding(TextBox.TextProperty, new Binding("/") 
{
    Source = strList,
    Mode = BindingMode.OneWay    
});

_txtBox4.SetBinding(TextBox.TextProperty, new Binding("/Length") 
{
    Source = strList,
    Mode = BindingMode.OneWay    
});

_txtBox5.SetBinding(TextBox.TextProperty, new Binding("/[2]") 
{
    Source = strList,
    Mode = BindingMode.OneWay    
});

// 没有Path的Source
string myStr = "hfdahfdlh;ahdfhfsahdfhasdfa";
_txtBox6.SetBinding(TextBox.TextProperty, new Binding(".")
{
    Source = myStr,
    Mode = BindingMode.OneWay    
});


 
参考:《深入浅出WPF》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郎涯技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值