绑定

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>

WPF 笔记 三 绑定

 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,宽,高。

WPF 笔记 三 绑定

 

 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));
        }
    }

WPF 笔记 三 绑定

 

 

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>

WPF 笔记 三 绑定

 

 

例子2:

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

WPF 笔记 三 绑定

 

Binding 为空等效于

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

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

 

相关文章:

  • 2022-12-23
  • 2021-10-19
  • 2021-09-24
  • 2021-12-13
  • 2021-06-02
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-07-28
  • 2021-12-02
  • 2021-10-18
  • 2022-12-23
  • 2021-08-28
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案