WPF 数据绑定

绑定对象:

数据绑定关键是System.Windows.Data.Binding对象,会将2个属性粘在一起,并在它们间建立通信信道。

1.代码实现绑定

//创建一绑定对象
Binding binding = new Binding();
//设置数据源对象(此处数据源来至textBox1)
binding.Source = textBox1;
//设置数据源对象的哪一个属性提供数据
binding.Path = new PropertyPath("Text");
//将textBlock1的依赖属性Text和绑定对象关联
textBlock1.SetBinding(TextBlock.TextProperty, binding);
//绑定的另一种方法,第一个参数为DependencyObject对象
//支持不是从FrameworkElement或FrameworkContentElement继承而来的对象数据绑定
//BindingOperations.SetBinding(textBlock1, TextBlock.TextProperty, binding);
//移除绑定
//BindingOperations.ClearBinding(textBlock1, TextBlock.TextProperty);

 

2.XAML中实现绑定

<TextBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" 
            Name="textBox1" VerticalAlignment="Top" Width="120" />
<!-- 此处Binding用无参构函构造,后在设置其2个属性值 -->
<TextBlock Height="23" HorizontalAlignment="Left" Margin="12,41,0,0" 
            Name="textBlock1" VerticalAlignment="Top"
            Text="{Binding ElementName=textBox1, Path=Text}" />
<!-- 另一绑定方式:此处Binding用含一个参数构函构造,后在设置其1个属性值 -->
<TextBlock Height="23" HorizontalAlignment="Left" Margin="12,41,0,0" 
            Name="textBlock1" VerticalAlignment="Top"
            Text="{Binding Text, ElementName=textBox1}" />

注意:XAML使用Binding的ElementName属性设置源对象,其实这2个属性都有效,只是在XAML中使用ElementName更方便,只需给源元素名就可以了。

           在XAML中设置Source,目标对象必须被定义在某Resources资源中。

<Page.Resources>
    <TextBox x:Key="textBox1" Text="lulu"></TextBox>
</Page.Resources>
<StackPanel>
    <!-- Binding使用Source指定目标元素 -->
    <TextBlock Height="23" HorizontalAlignment="Left" Margin="12,41,0,0" 
            Name="textBlock1" VerticalAlignment="Top"
            Text="{Binding Text, Source={StaticResource textBox1}}" />
</StackPanel>


与普通.NET属性绑定:

<Page.Resources>
    <!-- 定义一个集合 -->
    <ResourceDictionary x:Key="dictionary">
        <Color x:Key="1" A="255" R="255" G="255" B="255"/>
        <Color x:Key="2" A="255" R="255" G="0" B="0"/>
    </ResourceDictionary>
</Page.Resources>

<!-- Label值显示2,因为集合不是FrameworkElement也不是FrameworkContentElement,因此放在逻辑资源里通过StaticResource访问 -->
<Label Content="{Binding Count, Source={StaticResource dictionary}}" />

注:使用普通.NET属性为数据源绑定,因为没有依赖属性的自动变更机制,源属性值改变,目标属性不会变化。
 

绑定整个对象:

源属性(即Binding的Path属性)是可选的!省略该属性将制动绑定整个对象。

<!-- Label值显示:(集合) -->
<Label Content="{Binding Source={StaticResource dictionary}}" />


绑定到集合:

class PhotoModel
{
    private string _path;
    private string _name;
    private Image _image;

    public string Path
    {
        get { return _path; }
        set { _path = value; }
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    //构造函数
    public PhotoModel(string path, string name)
    {
        _path = path;
        _name = name;
    }

    //重写ToString(),可不指定元素DisplayMemberPath属性,显示需要显示的属性值
    public override string ToString()
    {
        return _path;
    }
}

//PhotoList继承ObservableCollection使得非依赖属性可实现自动跟新绑定值
class PhotoList : System.Collections.ObjectModel.ObservableCollection<PhotoModel>
{ }
/// <summary>
/// BindPage.xaml 的交互逻辑
/// </summary>
public partial class BindPage : Page
{
    PhotoList pl;
    public BindPage()
    {
        //创建数据源
        pl = new PhotoList();
        pl.Add(new PhotoModel("img/a.jpg", "a.jpg"));
        pl.Add(new PhotoModel("img/b.jpg", "b.jpg"));
        pl.Add(new PhotoModel("img/c.jpg", "c.jpg"));

        //将数据源添加到当前页的逻辑资源中
        Resources.Add("photoList", pl);

        InitializeComponent();
    }

    #region Event

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        //修改数据源
        pl.RemoveAt(pl.Count-1);
    }

    #endregion
}
<Page.Resources>
    <SolidColorBrush x:Key="red" Color="red" />
    <!-- 定义字典集合 -->
    <ResourceDictionary x:Key="dic" />
</Page.Resources>
    
<StackPanel>
    <Label Content="{Binding Count, Source={StaticResource dic}}" />
        
    <!-- 配置DisplayMemberPath要显示的PhotoModel元素中Name属性值 -->
    <!-- 配置IsSynchronizedWithCurrentItem可同步选中同一数据源Selector控件选择项 -->
    <ListBox x:Name="listBox1" DisplayMemberPath="Name" ItemsSource="{Binding Source={StaticResource photoList}}"
                IsSynchronizedWithCurrentItem="True"/>
    <ListBox x:Name="listBox2" DisplayMemberPath="Path" ItemsSource="{Binding Source={StaticResource photoList}}" 
                IsSynchronizedWithCurrentItem="True"/>
    <Button Height="33" Width="83" Content="修改数据源" Click="Button_Click" />
</StackPanel> 


DataContext共享源:

对于同一页面不同控件,绑定到同一源对象上,WPF可指定一隐式数据源,而不用显示调用Binding标记每个Source,RelativeSource,ElementName。这种隐式数据源也叫数据上下文(DataContext)。设置父元素的DataContext属性为这个源对象。

<StackPanel Name="parent" DataContext="{StaticResource photoList}">
    <!-- 配置DisplayMemberPath要显示的PhotoModel元素中Name属性值 -->
    <!-- 配置SelectedValuePath选中的Value值属性 -->
    <!-- 配置IsSynchronizedWithCurrentItem可同步选中同一数据源Selector控件选择项 -->
    <ListBox x:Name="listBox1" SelectedValuePath="Name" DisplayMemberPath="Name" ItemsSource="{Binding}"
                IsSynchronizedWithCurrentItem="True"/>
    <ListBox x:Name="listBox2" DisplayMemberPath="Path" ItemsSource="{Binding}"
                IsSynchronizedWithCurrentItem="True"/>
    <Button Height="33" Width="83" Content="修改数据源" Click="Button_Click" />
</StackPanel> 

用代码实现DataContext

InitializeComponent();
//在InitializeComponent()后调用,否者parent元素对象还未构建成功,会报错
//用此种方法可以避免将数据源对象保存为一资源
parent.DataContext = pl;

 

控制呈现:

1.使用数据模板

数据模板是一种用户界面。

<StackPanel Name="parent">
    <ListBox x:Name="listBox1" SelectedValuePath="Name" ItemsSource="{Binding}"
        IsSynchronizedWithCurrentItem="True" SelectionChanged="listBox2_SelectionChanged">
        <ListBox.ItemTemplate>
            <!-- 数据模板,用于显示一个图片 -->
            <!-- DataTemplate通常被当做一资源,可为多个元素共享,无论属性元素在哪里 -->
            <DataTemplate DataType="Button">
                <!-- 注:此Path非彼Path,是指PhotoModel对象中Path属性 -->
                <Image Source="{Binding Path}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <!-- button显示:img/a.jpg -->
    <Button Name="button1" Height="33" Width="83" Content="{Binding Path}" Click="Button_Click" />
</StackPanel>


2.使用值转换器

namespace WPF_Test
{
    //绑定值笔刷转换器
    class CountToBackgroundConverter : IValueConverter
    {

        #region IValueConverter 成员

        //源实例转换为目标实例
        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            //检查当前转换目标是否为Brush对象
            if(targetType != typeof(Brush))
            {
                throw new InvalidOperationException("转换目标必须为Brush!");
            }

            int id = int.Parse(value.ToString());

            switch(id)
            {
                case 1:
                    return Brushes.YellowGreen;
                case 2:
                    return Brushes.Orange;
                case 3:
                    return Brushes.SkyBlue;
                default:
                    //返回用户定义的参数
                    return parameter;
            }
        }

        //目标实例转换为源实例
        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new System.NotImplementedException();
        }

        #endregion
    }

    //格式化绑定值转换器
    class FormatConverter : IValueConverter
    {

        #region IValueConverter 成员

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int num = int.Parse(value.ToString());

            return num + (num <= 1 ? "Item" : "Items");
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
<!-- 在当前Page中引用自定义命名空间 -->
xmlns:custom="clr-namespace:WPF_Test"

<Page.Resources>  
<!-- 定义自定义类 -->
    <custom:CountToBackgroundConverter x:Key="myConverter"/>
    <custom:FormatConverter x:Key="myFormatConverter"/>
</Page.Resources>
<StackPanel Name="parent">
    <ListBox x:Name="listBox1" SelectedValuePath="Name" ItemsSource="{Binding}">
        <ListBox.ItemTemplate>
            <DataTemplate DataType="Button">
                    <StackPanel>
                        <!-- 使用Binding的Converter属性插入自定义值转换器,将绑定数据ID值转换为需要的Brushes类型 -->
                        <Label Background="{Binding ID, ConverterParameter=Red, 
                            Converter={StaticResource myConverter}}" Content="{Binding Name}"/>
                    </StackPanel> 
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <!-- 每次源值改变,Convert方法都会调用 -->
    <Label Content="{Binding Count, Converter={StaticResource myFormatConverter}}" />
    <!-- button显示:img/a.jpg -->
    <Button Name="button1" Height="33" Width="83" Content="{Binding Path}" Click="Button_Click" />
</StackPanel>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值