WPF数据绑定点滴1,2,3

在WPF程序设计中数据绑定非常常用,这个功能使用得当可以大幅的简化程序逻辑,提高效率,如下根据使用中的情况简要做了总结。

概念

数据绑定发生在源对象和目标对象之间,当源对象或目标对象的属性值发生改变时,所绑定的对象也会跟着发生改变
         * 数据绑定的目标对象一定是Dependency Object,所绑定的目标对象的属性一定是Dependency Property
         * 源对象可以是Dependency Object/Dependency Property,也可以是一般的.net对象

绑定模式:

         *  OneWay:源对象发生改变时,目标对象也跟着改变;目标对象发生改变时,源对象不变化
         *  TwoWay:源对象发生改变时,目标对象也跟着改变;目标对象发生改变时,源对象也跟着变化
         *  OneTime:只在初始化时发生作用,数据从源对象传递到目标对象
         *  OneWayToSource:和OneWay类似,不同的是源对象随着目标对象的变化而变化
         *  Default:源对象的属性如果是只读的,选择为OneWay;如果源对象的属性是读写的,选择为TwoWay,大多的情况 适用
      对象是否实现了INotifyPropertyChanged,是选择绑定的依据
【初次使用常迷惑的问题是,绑定的.net对象修改时,而目标不变化,此时主要的问题是一般的.net对象没有实现INotifyPropertyChanged的原因;对于集合的绑定也类似,可以使用ObservableCollection <T>这个容器类构造集合辅助处理】

Binding.Path

绑定的路径设置,可以选择各种形式,从属性、数组、XPath等等

MSDN有详细说明: http://msdn.microsoft.com/zh-cn/library/system.windows.data.binding.path.aspx 

///Binding.Path Property 的类型
///Path=PropertyName
///Path=ShoppingCart.Order
///Path=(DockPanel.Dock).
///Path=ShoppingCart.ShippingInfo[MailingAddress,Street]
///Path="[(sys:Int32)42,(sys:Int32)24]"
///Path=/
///Path=/Offices/ManagerName
///Path=.

基本使用例子

        <!--界面对象之间的绑定-->
        <ScrollBar Name="scroll"  Orientation ="Horizontal " Margin ="24"
               Maximum ="100" LargeChange ="10" SmallChange ="1"/>

        <TextBox Name="txtScrollvalue"/>
        <TextBox Text="{Binding ElementName=scroll, Path=Value}"/>
        <TextBox>
            <TextBox.Text>
                <Binding ElementName="scroll" Path="Value"/>
            </TextBox.Text>
        </TextBox>
 
        <!--绑定时刻:控制更新的时刻-->
        <TextBox Text="{Binding ElementName=scroll, Path=Value, UpdateSourceTrigger=PropertyChanged}"/>
        <!--DataContext形式绑定-->
        <StackPanel Name="objectBind">
            <TextBox Text="{Binding Path=FirstName, Mode=OneWay}"/>
            <TextBox Text="{Binding Path=LastName}"/>
            <ListBox  ItemsSource="{Binding Path=Address}" Height="50" Width="380"   IsSynchronizedWithCurrentItem ="True" />
            <ComboBox  Name="phs" ItemsSource="{Binding Path=Phones}" DisplayMemberPath="Mobile" Height="20" Width="380"/>
           
            <TextBox Text="{Binding Path=Phones[0].Mobile}"/>
        </StackPanel>
如下是对应如上的代码
this.person = new Person("joe", "bill")
{
    Address = new List<string>() { "Beijing", "China" },
    Phones = new List<Phones>()
    {
        new Phones(){ Mobile="131", Phone="112"},
        new Phones(){ Mobile="132", Phone="110"}
    },
};
this.person.RecentPohne = this.person.Phones[1];

this.objectBind.DataContext = this.person;

 

类型转换

对于绑定中设置的不同类型很常用,如我们常见的日期的显示等都可以采用这种形式转换为符合自己需要的形式

        <StackPanel.Resources>
            <local:NumberConvert  x:Key="cvt"/>
        </StackPanel.Resources>
        <!--绑定类型转换-->
        <TextBox Name="octText" />
        <TextBox Text="{Binding ElementName=octText, Path=Text, Converter={StaticResource cvt },ConverterParameter=2 }">
        </TextBox>
以下是NumberConvert的实现

[ValueConversion(typeof(string), typeof(int))]
public class NumberConvert : IValueConverter
{
    public object Convert(object value, Type typeTarget, object param, CultureInfo culture)
    {
        string inputValue = value.ToString();
        int c;
        int.TryParse(inputValue, out c);
        if (param != null)
        {
            var p = Int32.Parse(param as string);
            c += p;
        }

        return c;
    }

    public object ConvertBack(object value, Type typeTarget, object param, CultureInfo culture)
    {
        int c;
        int.TryParse(value.ToString(), out c);
        if (param != null)
        {
            var p = Int32.Parse(param as string);
            c -= p;
        }

        return c.ToString();
    }
}

 

数据校验

对于绑定的数据如果允许编辑,可以通过数据简要防止不符合要求的数据更新到对象中
        <TextBox Name="validRule" ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}">
        <TextBox.Text>
                <Binding Path="Count"  NotifyOnValidationError="true">
                    <Binding.ValidationRules>
                            <local:SelfValidRule Age="100"/>
                    </Binding.ValidationRules>
             </Binding>
        </TextBox.Text>
        </TextBox>

以下是SelfValidRule 的实现

public class SelfValidRule : ValidationRule
   {
       public int Age
       {
           get;
           set;
       }

       public SelfValidRule()
       {
       }

       public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
       {
           int age;
           if (!int.TryParse(value.ToString(), out age))
           {
               return new ValidationResult(false, "输入无效字符!");
           }

           if (age < 0 || age > this.Age)
           {
               return new ValidationResult(false, "太大!");
           }

           return ValidationResult.ValidResult;
       }
   }

复杂数据来源对象的绑定

在复杂的场合,我们可能需要把不同的数据对象绑定到界面元素上,此时我们可以使用如下的一些比较复杂的支持类辅助完成这些工作
         * MultiBinding CompositeCollection PriorityBinding

以上类可参考MSDN的详细解释。

以上例子的详细地址参考:

http://cid-56b433ad3d1871e3.office.live.com/self.aspx/.Public/wpf%5E_binding.rar

posted @ 2011-03-19 21:54  2012  阅读(3743)  评论(1编辑  收藏  举报