WPF数据绑定

发布时间 2023-11-24 11:41:13作者: ZHIZRL

依赖对象做为数据源

如果绑定的源是依赖对象的依赖属性,那么这个依赖属性发生实时变化的时候,会同步到绑定目标。

如果绑定的源是非依赖属性,那么这个属性发生变化的的时候,不会同步到绑定目标。

被绑定的数据源,需要是属性。

    <StackPanel>
        <!--目标对象:TextBlock-->
        <!--目标属性:Text-->
        <!--绑定数据源:tb_source-->
        <!--绑定路径:Text-->
        <!--SolidColorBrush  : Color-->
        <!--TextBox tb_source = new TextBox(){Text="Hello"}
        tb_source.ToString();-->
        <Grid>
            <TextBox Text="Hello" Name="tb_source" Foreground="Red"/>
        </Grid>
        <Grid>
            <TextBlock Text="{Binding ElementName=tb_source,Path=Text}"/>
        </Grid>
        <PasswordBox Password="123456" Name="pb"/>
        <TextBlock Text="{Binding ElementName=pb,Path=Password}"/>

        <!--1、如果绑定的源是依赖对象的依赖属性,那么这个依赖属性发生实时变化的时候,会同步到绑定目标-->
        <!--2、如果绑定的源是非依赖属性,那么这个属性发生变化的的时候,不会同步到绑定目标-->
        <!--3、被绑定的数据源,需要是属性-->
    </StackPanel>

TextBox的Text属性是依赖属性,变化时会同步到TextBlock的Text属性。

PasswordBox的Password是非依赖属性,变化是不会同步到TextBlock的Text属性。

普通数据类型或集合类型做为数据源

在Xmal中引入命名空间定义数据

        xmlns:sys="clr-namespace:System;assembly=mscorlib"
    <Window.Resources>
        <!--public int Value = 100;
            C#   定义一个int类型  默认就是32位的数据长度  4个字节-->
        <sys:Int32 x:Key="Value">100</sys:Int32>
        <sys:Int32 x:Key="V1">200</sys:Int32>

        <!--string[] list=new string[]{"AAAA","BBBB","CCCC"}-->
        <x:Array x:Key="list" Type="sys:String">
            <sys:String>AAAA</sys:String>
            <sys:String>BBBB</sys:String>
            <sys:String>CCCC</sys:String>
        </x:Array>
    </Window.Resources>
    <StackPanel>
        <TextBlock Text="{Binding Source={StaticResource Value},Path=.}" Name="tb"/>
        <TextBlock Text="{Binding Path=.}" DataContext="{StaticResource Value}"/>

        <!--Binding对象内部属性(Source)数据源优先级更高-->
        <TextBlock Text="{Binding Source={StaticResource V1},Path=.}" DataContext="{StaticResource Value}"/>

        <!--1、目前两种形式的数据源:
            依赖对象(页面上的对象,指定名称),通过ElementName建立数据源联系
            普通数据数据,演示是通过Source建立数据源联系,
                   同时也可以使用目标对象的DataContext属性进行数据源的关联
                           一般不使用DataContext属性进行数据源的关联-->


        <TextBlock Text="{Binding Source={StaticResource list},Path=[2]}"/>
        <ListBox ItemsSource="{Binding Source={StaticResource list}}"/>

        <TextBlock Text="{Binding ElementName=win,Path=Value}"/>
    </StackPanel>

单个对象做为数据源

声明一个类做为数据源

namespace Zhaoxi.BindingLesson.DataSource
{
    public class Person
    {
        public int Age { get; set; }
        public string Name { get; set; }
    }
}
    <Window.Resources>
        <!--Person p = new Person();-->
        <local:Person x:Key="p" Age="30" Name="Michael"/>

        <Button x:Key="button" Width="300" Tag="sfseg"/>
    </Window.Resources>
    <StackPanel>
        <TextBlock Text="{Binding Source={StaticResource p},Path=Name}"/>
        <TextBlock Text="{Binding Source={StaticResource p},Path=Age}"/>
        <TextBlock Text="{Binding Source={StaticResource button},Path=Tag}"/>
    </StackPanel>

ADO.NET数据做为数据源

获取数据

    public partial class ADODataSourceWindow : Window
    {
        public ADODataSourceWindow()
        {
            InitializeComponent();



            string connectstring = "data source=localhost;database=test;user id=root;password=123456;pooling=true;charset=utf8;";
            using MySqlConnection conn = new MySqlConnection(connectstring);
            conn.Open();

            MySqlDataAdapter adapter = new MySqlDataAdapter("select * from user_list", conn);
            DataTable dataTable = new DataTable();
            adapter.Fill(dataTable);

            this.lv.ItemsSource = dataTable.DefaultView;
        }
    }
    <Grid>
        <ListView Name="lv">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="id" Width="50" DisplayMemberBinding="{Binding _id}"/>
                    <GridViewColumn Header="user_id" Width="150" DisplayMemberBinding="{Binding user_id}"/>
                    <GridViewColumn Header="user_name" Width="300" DisplayMemberBinding="{Binding user_name}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>

Linq结果做为数据源

    public partial class LinqDataSourceWindow : Window
    {
        public LinqDataSourceWindow()
        {
            InitializeComponent();

            string connectstring = "data source=localhost;database=test;user id=root;password=123456;pooling=true;charset=utf8;";
            using MySqlConnection conn = new MySqlConnection(connectstring);
            conn.Open();

            MySqlDataAdapter adapter = new MySqlDataAdapter("select * from user_list", conn);
            DataTable dataTable = new DataTable();
            adapter.Fill(dataTable);

            //new List<string>() { }

            this.lv.ItemsSource = from q in dataTable.AsEnumerable()
                                  where q.Field<string>("user_name").ToString() == "Jovan"
                                  select new
                                  {
                                      ID = int.Parse(q["_id"].ToString()),
                                      UserId = q.Field<string>("user_id").ToString(),
                                      UserName = q.Field<string>("user_name").ToString()
                                  };

            //this.lv.ItemsSource = result;
        }
    }
    <Grid>
        <ListView Name="lv">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="id" Width="50" DisplayMemberBinding="{Binding _id}"/>
                    <GridViewColumn Header="user_id" Width="150" DisplayMemberBinding="{Binding user_id}"/>
                    <GridViewColumn Header="user_name" Width="300" DisplayMemberBinding="{Binding user_name}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>

ObjectDataProvider做为数据源

在MethodObject类中定义一个Calculator方法

namespace Zhaoxi.BindingLesson.DataSource
{
    public class MethodObject
    {
        public double Calculator(string value)
        {
            return double.Parse(value) * 100;
        }
    }
}
    <Window.Resources>
        
        <ObjectDataProvider x:Key="odp"
                            ObjectType="{x:Type local:MethodObject}"
                            MethodName="Calculator">
            <ObjectDataProvider.MethodParameters>
                <sys:String>2.0</sys:String>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        
    </Window.Resources>
    <StackPanel>
        <TextBlock Text="{Binding Source={StaticResource odp},Path=.}"/>
        <!--这个绑定有点特殊,特殊在绑定的源是ObjectDataProvider的参数-->
        <TextBox Text="{Binding Source={StaticResource odp},Path=MethodParameters[0],BindsDirectlyToSource=True}"/>
        <TextBox/>
    </StackPanel>

RelativeSource指定数据源

    <Window.Resources>
        <ControlTemplate x:Key="BtnTemp" TargetType="Button">
            <Border Background="{Binding Path=Background,RelativeSource={RelativeSource Mode=TemplatedParent}}"
                    Width="{TemplateBinding Width }"
                    Height="{TemplateBinding Height}">
                <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
                <!--数据源要求可编辑,Text默认是双向绑定-->
                <!--<TextBox Text="{Binding ActualWidth,Mode=OneWay,RelativeSource={RelativeSource Mode=TemplatedParent}}"/>-->
            </Border>
        </ControlTemplate>
    </Window.Resources>
    <Window.DataContext>
        <local:Person Name="Aloha Sun" Age="30"/>
    </Window.DataContext>
    <Grid>
        <StackPanel>
            <StackPanel.DataContext>
                <local:Person Name="麦子熟了" Age="28"/>
            </StackPanel.DataContext>
            <!--<TextBlock Text="{Binding Path=Title, ElementName=win}" Foreground="Red" />-->
            <!--<TextBlock Text="{Binding Path=[1]}" Foreground="Red" />-->
            <TextBlock Text="{Binding Path=Name}" Foreground="Red" />
            <!--Mode=FindAncestor 查找祖先-->
            <TextBlock Text="{Binding Path=DataContext.Age,
                RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}" Foreground="Red" />

            <TextBlock Text="{Binding ElementName=win,Path=DataContext.Age}"/>
            <!--Mode=Self 查找自己-->
            <TextBlock Text="{Binding Path=Foreground,
                RelativeSource={RelativeSource Mode=Self}}" Foreground="#FF9000" />

            <Button Content="Button" Template="{StaticResource BtnTemp}"
                    Background="Orange" Tag="123"/>
        </StackPanel>
    </Grid>