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

            "{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 userButton>
            <Button Name="btnChangeUser" Click="btnChangeUser_Click" Margin="0,5">Change userButton>
            <Button Name="btnDeleteUser" Click="btnDeleteUser_Click">Delete userButton>
        StackPanel>
        <ListBox Name="lbUsers" DisplayMemberPath="Name">ListBox>
    DockPanel>

后台

    public partial class MainWindow : Window
    {
        private ObservableCollection users = new ObservableCollection();
        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));
        }
    }