zoukankan      html  css  js  c++  java
  • WPF中的数据绑定Data Binding使用小结

    完整的数据绑定的语法说明可以在这里查看:

    http://www.nbdtech.com/Free/WpfBinding.pdf

    MSDN资料:

    Data Binding: Part 1 http://msdn.microsoft.com/en-us/library/aa480224.aspx

    Data Binding: Part 2 http://msdn.microsoft.com/en-us/library/aa480226.aspx

    Data Binding Overview http://msdn.microsoft.com/en-us/library/ms752347.aspx

     

          INotifyPropertyChanged接口   绑定的数据源对象一般都要实现INotifyPropertyChanged接口。

         {Binding}  说明了被绑定控件的属性的内容与该控件的DataContext属性关联,绑定的是其DataContext代表的整个控件的内容。如下:
    <ContentControl Name="LongPreview" Grid.Row="2" Content="{Binding}" HorizontalAlignment="Left"/>
    ContentControl 只是一个纯粹容纳所显示内容的一个空控件,不负责如何具体显示各个内容,借助于DataTemplate可以设置内容的显示细节。

         使用参数Path

    (使用父元素的DataContext)使用参数绑定,且在数值变化时更新数据源。(两种写法)

    <TextBox Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}"/>
    <TextBox.Text>
    <Binding Path="StartPrice" UpdateSourceTrigger="PropertyChanged"/>
    </TextBox.Text>

         相对资源RelativeSource

    RelativeSource={RelativeSource Self}是一个特殊的绑定源,表示指向当前元素自己。自己绑定自己,将ToolTip属性绑定到Validation.Errors中第一个错误项的错误信息(Validation.Errors)[0].ErrorContent。

    绑定:相对资源
    <Style x:Key="textStyleTextBox" TargetType="{x:Type TextBox}">
    <Setter Property="Foreground" Value="#333333" />
    <Setter Property="MaxLength" Value="40" />
    <Setter Property="Width" Value="392" />
    <Style.Triggers>
    <Trigger Property="Validation.HasError" Value="true">
    <Setter Property="ToolTip"
    Value
    ="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
    </Trigger>
    </Style.Triggers>
    </Style>

         使用转换器和验证规则

    绑定:转换器和验证规则
    <TextBox Name="StartDateEntryForm" Grid.Row="3" Grid.Column="1" Style="{StaticResource textStyleTextBox}" Margin="8,5,0,5" Validation.ErrorTemplate="{StaticResource validationTemplate}">
    <TextBox.Text>
    <Binding Path="StartDate" UpdateSourceTrigger="PropertyChanged" Converter="{StaticResource dateConverter}">
    <Binding.ValidationRules>
    <src:FutureDateRule/>
    </Binding.ValidationRules>
    </Binding>
    </TextBox.Text>
    </TextBox>

    //自定义的验证规则须从ValidationRule继承。
    class FutureDateRule : ValidationRule
    {
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
    DateTime date;
    try
    {
    date = DateTime.Parse(value.ToString());
    }
    catch (FormatException)
    {
    return new ValidationResult(false, "Value is not a valid date.");
    }
    if (DateTime.Now.Date > date)
    {
    return new ValidationResult(false, "Please enter a date in the future.");
    }
    else
    {
    return new ValidationResult(true, null);
    }
    }
    }

         使用数据触发器

    SpecialFeatures是一个枚举数据类型。

    绑定:数据触发器
    <DataTrigger Binding="{Binding Path=SpecialFeatures}">
    <DataTrigger.Value>
    <src:SpecialFeatures>Color</src:SpecialFeatures>
    </DataTrigger.Value>
    <Setter Property="BorderBrush" Value="DodgerBlue" TargetName="border" />
    <Setter Property="Foreground" Value="Navy" TargetName="descriptionTitle" />
    <Setter Property="Foreground" Value="Navy" TargetName="currentPriceTitle" />
    <Setter Property="BorderThickness" Value="3" TargetName="border" />
    <Setter Property="Padding" Value="5" TargetName="border" />
    </DataTrigger>

        多重绑定

        绑定源是多个源,绑定目标与绑定源是一对多的关系。

    多重绑定
    <ComboBox.IsEnabled>
    <MultiBinding Converter="{StaticResource specialFeaturesConverter}">
    <Binding Path="CurrentUser.Rating" Source="{x:Static Application.Current}"/>
    <Binding Path="CurrentUser.MemberSince" Source="{x:Static Application.Current}"/>
    </MultiBinding>
    </ComboBox.IsEnabled>
    //自定义的转换器须实现IMultiValueConverter接口。
    class SpecialFeaturesConverter : IMultiValueConverter
    {
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    //数组中的对象数值的索引顺序与XAML文件的多重绑定定义有关。
    int rating = (int)values[0];
    DateTime date = (DateTime)values[1];

    return ((rating >= 10) && (date.Date
    < (DateTime.Now.Date - new TimeSpan(365, 0, 0, 0))));
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
    return new object[2] { Binding.DoNothing, Binding.DoNothing };
    }
    }

        Master-Detail:主-从应用(使用CollectionViewSource)

    主从应用
    <CollectionViewSource Source="{Binding Source={x:Static Application.Current}, Path=AuctionItems}" x:Key="listingDataView"/>
    <ListBox Name="Master" Grid.Row="2" Grid.ColumnSpan="3" Margin="8" ItemsSource="{Binding Source={StaticResource listingDataView}}">
    </ListBox>
    <ContentControl Name="Detail" Grid.Row="3" Grid.ColumnSpan="3" Margin="9,0,0,0" Content="{Binding Source={StaticResource listingDataView}}" ContentTemplate="{StaticResource detailsProductListingTemplate}"/>

    说明:
    AuctionItems的定义为:public ObservableCollection<AuctionItem> AuctionItems  。
    在 ListBox 中直接使用 CollectionViewSource 来表示主数据(AuctionItem集合),在 ContentControl 中则同时使用设定 Content 和 ContentControl 两个属性, Content 直接指向CollectionViewSource, ContentControl 则使用先前已经定义的数据模板绑定(数据模板中的数据项则是绑定到AuctionItem类的各个属性)。

         数据分组(使用CollectionViewSource)
    分组表头项的数据模板:
    <DataTemplate x:Key="groupingHeaderTemplate">
        <TextBlock Text="{Binding Path=Name}" Foreground="Navy" FontWeight="Bold" FontSize="12" />
    </DataTemplate>

    在ListBox中使用分组:
    <ListBox Name="Master" Grid.Row="2" Grid.ColumnSpan="3" Margin="8" ItemsSource="{Binding Source={StaticResource listingDataView}}">
        <ListBox.GroupStyle>
            <GroupStyle HeaderTemplate="{StaticResource groupingHeaderTemplate}"/>
        </ListBox.GroupStyle>
    </ListBox>
    分组开关:
    <CheckBox Name="Grouping" Grid.Row="1" Grid.Column="0" Margin="8" Style="{StaticResource checkBoxStyle}" Checked="AddGrouping" Unchecked="RemoveGrouping">Group by category</CheckBox>
    CheckBox的事件处理:
    private void AddGrouping(object sender, RoutedEventArgs e)
    {
        PropertyGroupDescription pgd = new PropertyGroupDescription();
        pgd.PropertyName = "Category"; //使用属性Category的数值来分组
        listingDataView.GroupDescriptions.Add(pgd);
    }
    private void RemoveGrouping(object sender, RoutedEventArgs e)
    {
        listingDataView.GroupDescriptions.Clear();
    }

         排序数据(使用CollectionViewSource) 比分组简单
    排序开关:
    <CheckBox Name="Sorting" Grid.Row="1" Grid.Column="3" Margin="8" Style="{StaticResource checkBoxStyle}" Checked="AddSorting" Unchecked="RemoveSorting">Sort by category and date</CheckBox>
    CheckBox的事件处理:
    private void AddSorting(object sender, RoutedEventArgs e)
    {
        listingDataView.SortDescriptions.Add(new SortDescription("Category", ListSortDirection.Ascending));
        listingDataView.SortDescriptions.Add(new SortDescription("StartDate", ListSortDirection.Descending));
    }
    private void RemoveSorting(object sender, RoutedEventArgs e)
    {
        listingDataView.SortDescriptions.Clear();
    }

         过滤数据(使用CollectionViewSource) 跟排序类似
    过滤开关:
    <CheckBox Name="Filtering" Grid.Row="1" Grid.Column="1" Margin="8" Style="{StaticResource checkBoxStyle}" Checked="AddFiltering" Unchecked="RemoveFiltering">Show only bargains</CheckBox>
    CheckBox的事件处理:
    private void AddFiltering(object sender, RoutedEventArgs e)
    {
        listingDataView.Filter += new FilterEventHandler(ShowOnlyBargainsFilter);
    }
    private void RemoveFiltering(object sender, RoutedEventArgs e)
    {
        listingDataView.Filter -= new FilterEventHandler(ShowOnlyBargainsFilter);
    }
    private void ShowOnlyBargainsFilter(object sender, FilterEventArgs e)
    {
        AuctionItem product = e.Item as AuctionItem;
        if (product != null)
        {
            //设置e.Accepted的值即可
            e.Accepted = product.CurrentPrice < 25;
        }
    }

  • 相关阅读:
    ECMAScript6 入门 函数的扩展
    ECMAScript6 入门-let与const命令
    编码规范
    webpack常用插件
    JS与CSS那些特别小的知识点区别
    常见数组方法及细节
    JS库
    Object冷知识
    html5-语义化标签
    Css继承属性和非继承属性
  • 原文地址:https://www.cnblogs.com/glowworm/p/1760977.html
Copyright © 2011-2022 走看看