• WPF 笔记 三 绑定


    绑定

    HelloWorld

        <StackPanel Margin="10">
            <TextBox Name="txtValue" />
            <WrapPanel Margin="0,10">
                <TextBlock Text="Value: " FontWeight="Bold" />
                <TextBlock Text="{Binding Path=Text, ElementName=txtValue}" />
            </WrapPanel>
        </StackPanel>

     Binding 语法

    {Binding Path=NameOfProperty}

    简略为

    {Binding NameOfProperty}

    连接其他UI元素的语法

    {Binding Path=Text, ElementName=txtValue}

    。。

     DataContext

        <StackPanel Margin="15">
            <WrapPanel>
                <TextBlock Text="Window title:  " />
                <TextBox Text="{Binding Title}" Width="150" />
            </WrapPanel>
            <WrapPanel Margin="0,10,0,0">
                <TextBlock Text="Window dimensions: " />
                <TextBox Text="{Binding Width}" Width="50" />
                <TextBlock Text=" x " />
                <TextBox Text="{Binding Height}" Width="50" />
            </WrapPanel>
        </StackPanel>

    在cs文件中

    InitializeComponent();
                this.DataContext = this;

    xaml绑定的property都是Window对象自身比如title,宽,高。

     Window本身的这些属性改变时,值会立即反映到UI显示上。

    如果UI上的值改变,需要焦点移动到其他UI控件,Window的那些宽高才会改变。此时UpdateSourceTrigger的值为LostFocus

    如果需要Window的那些宽高立即生效的话,binding后面加上UpdateSourceTrigger=PropertyChanged

                <TextBox Text="{Binding Width,UpdateSourceTrigger=PropertyChanged}" Width="50" />

    UpdateSourceTrigger的值一共有

    1.Explicit

    2.LostFocus

    3.PropertyChanged

    对于Explicit,这基本上意味着除非您手动执行,否则不会更新源。

    explicit手动更新的例子:

                <TextBox Name="txtWindowTitle" Text="{Binding Title, UpdateSourceTrigger=Explicit}" Width="150" />

    后台代码

                BindingExpression binding = txtWindowTitle.GetBindingExpression(TextBox.TextProperty);
                binding.UpdateSource();

    后台代码实现HelloWorld例子中的绑定

        <StackPanel Margin="10">
            <TextBox Name="txtValue" />
            <WrapPanel Margin="0,10">
                <TextBlock Text="Value: " FontWeight="Bold" />
                <TextBlock Name="lblValue" />
            </WrapPanel>
        </StackPanel>
                InitializeComponent();
                Binding binding = new Binding("Text");
                binding.Source = txtValue;
                lblValue.SetBinding(TextBlock.TextProperty, binding);

     响应数据变化

        <DockPanel Margin="10">
            <StackPanel DockPanel.Dock="Right" Margin="10,0,0,0">
                <Button Name="btnAddUser" Click="btnAddUser_Click">Add user</Button>
                <Button Name="btnChangeUser" Click="btnChangeUser_Click" Margin="0,5">Change user</Button>
                <Button Name="btnDeleteUser" Click="btnDeleteUser_Click">Delete user</Button>
            </StackPanel>
            <ListBox Name="lbUsers" DisplayMemberPath="Name"></ListBox>
        </DockPanel>

    后台

        public partial class MainWindow : Window
        {
            private ObservableCollection<User> users = new ObservableCollection<User>();
            public MainWindow()
            {
                
                InitializeComponent();
                users.Add(new User() { Name = "John Doe" });
                users.Add(new User() { Name = "Jane Doe" });
    
                lbUsers.ItemsSource = users;
            }
            private void btnAddUser_Click(object sender, RoutedEventArgs e)
            {
                users.Add(new User() { Name = "New user" });
            }
    
            private void btnChangeUser_Click(object sender, RoutedEventArgs e)
            {
                if (lbUsers.SelectedItem != null)
                    (lbUsers.SelectedItem as User).Name = "Random Name";
            }
    
            private void btnDeleteUser_Click(object sender, RoutedEventArgs e)
            {
                if (lbUsers.SelectedItem != null)
                    users.Remove(lbUsers.SelectedItem as User);
            }
    
        }
    
        public class User : INotifyPropertyChanged
        {
            private string name;
            public string Name
            {
                get { return this.name; }
                set
                {
                    if (this.name != value)
                    {
                        this.name = value;
                        this.NotifyPropertyChanged("Name");
                    }
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            public void NotifyPropertyChanged(string propName)
            {
                if (this.PropertyChanged != null)
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

    Binding Source RelativeSource

    Source

    Source属性通常用于绑定设置的对象时,是已知的

     <Window x:Name="MainWindow">
             <Grid>
                   <Button Background=”{Binding Source={StaticResource ButtonStyle}}”/>
             </Grid>
    </Window>

    RelativeSource

    由于不能确定Source的对象叫什么名字,但知道它与作为Binding目标的对象在UI布局上有相对关系,比如控件自己关联自己的某个数据、关联自己某级容器的数据,就要使用Binding的RelativeSource属性。

         RelativeSource 的三种典型用法:

     /1.UI元素的一个属性绑定在自身的另一个属性上

    <Label Background = {Binding Path=Forgroud, RelativeSource={RelativeSource Self}} />

         /2.UI元素的一个属性绑定在某个父元素的属性上

    <Grid>
       <Label Background = {Binding Path=Background, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}/>
    </Grid>

         /3.Template中的元素的属性绑定在Template使用者元素的属性上

      {Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}

    如果要绑定到对象上的另一个属性:

    {Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}

    如果您想获得祖先的属性:

    {Binding Path=PathToProperty,
        RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}

    如果希望获得模板父级上的属性(因此可以在ControlTemplate中执行双向绑定)

    {Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}

    或者,更短的(这只适用于OneWay绑定):

    {TemplateBinding Path=PathToProperty}

        

    例子1:

         <StackPanel DataContext="abc">
            <Label Content="{Binding}"></Label>
            <Label Content="{Binding RelativeSource={RelativeSource Self},Path=DataContext}"></Label>
        </StackPanel>

    例子2:

        <StackPanel DataContext="abc">
            <Label Content="{Binding}"></Label>
            <Label DataContext="def" Content="{Binding RelativeSource={RelativeSource Self},Path=DataContext}"></Label>
        </StackPanel>

    Binding 为空等效于

    {Binding RelativeSource={RelativeSource Self},Path=DataContext}

     从本控件类为开始根据可视树的层次结构自下而上查找不为空的Datacontext属性的值。

  • 相关阅读:
    iframe的使用小贴士
    jquery M97-datepicker日历控件
    CSS z-index 属性的使用方法和层级树的概念
    常用的js代码
    图片水平垂直居中
    server端和前端的区别
    nodejs模块化标准
    nodejs介绍
    小程序缓存Storage的基本用法
    小程序数据绑定的拓展用法
  • 原文地址:https://www.cnblogs.com/noigel/p/15864556.html
Copyright © 2020-2023  润新知