WPF ObservableCollection<T>

1. ObservableCollection<T> 类    表示一个动态数据集合,在添加项、移除项或刷新整个列表时,此集合将提供通知。

为什么ObservableCollection<T> 绑定后能自动更新UI ?

ObservableCollection<T> 类,它是实现 INotifyCollectionChanged 接口的数据集合的内置实现。

2.  还有一种情况(T类型) 对象的属性 发生变化时 需要通知到UI界面,此时就需要T类型实现 INotifyPropertyChange接口。比如下面例子中的 Students 就需要实现INotifyPropertyChange 接口

3.我们如果在点击事件里面给infos赋值一个新的集合数据。会发现数据并没有变更。这是因为infos这个集合的地址变更并没有实现通知机制。当我们new一个对象赋值给infos时候,infos的地址指向变更了。    解决方式 我们写了一个ViewModel类,并实现INotifyPropertyChanged接口,ViewModel类里面有一个属性 

ObservableCollection<Students> StudentList。也是说我们进一步封装,将数据源封装成 ViewModel类的属性。

由此可见 WPF的数据绑定  要求绑定的对象地址不能发生变化,也就是赋值给DataContext的对象地址不能发生变化,  变化的只是对象里面的属性.

界面代码

<Window x:Class="ObservableCollection集合绑定.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ObservableCollection集合绑定"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel Height="295" HorizontalAlignment="Left" Margin="10,10,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="427">
            <TextBlock Height="23" Name="textBlock1" Text="学员编号:" />
            <TextBox Height="23" Name="txtStudentId" Width="301" HorizontalAlignment="Left"/>
            <TextBlock Height="23" Name="textBlock2" Text="学员列表:" />
            <ListBox Height="156" Name="lbStudent" Width="305" HorizontalAlignment="Left" ItemsSource="{Binding StudentList}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Name="stackPanel2" Orientation="Horizontal">
                            <TextBlock  Text="{Binding Id,Mode=TwoWay}" Margin="5" Background="Beige"/>
                            <TextBlock Text="{Binding Name,Mode=TwoWay}" Margin="5"/>
                            <TextBlock  Text="{Binding Age,Mode=TwoWay}" Margin="5"/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <Button Content="Button" Height="23" Name="button1" Width="75" HorizontalAlignment="Left" Click="button1_Click" />
        </StackPanel>
    </Grid>
</Window>

C#后台代码:

    public partial class MainWindow : Window
    {
        readonly ViewModel viewModel = new ViewModel();
        public MainWindow()
        {
            InitializeComponent();
            viewModel.StudentList = new ObservableCollection<Students>()
            {
            new Students(){ Id=1, Age=11, Name="Tom"},
            new Students(){ Id=2, Age=12, Name="Darren"},
            new Students(){ Id=3, Age=13, Name="Jacky"},
            new Students(){ Id=4, Age=14, Name="Andy"}
            };
            this.lbStudent.DataContext = viewModel;

            //创建绑定对象
            var binding = new Binding("SelectedItem.Id");
            //设置绑定源
            binding.Source = lbStudent;
            binding.Mode = BindingMode.OneWay;
            this.txtStudentId.SetBinding(TextBox.TextProperty, binding);
        }
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            viewModel.StudentList = new ObservableCollection<Students>()
            {
            new Students(){ Id=19, Age=111, Name="这是变化后的集合"},
            new Students(){ Id=29, Age=121, Name="这是变化后的集合"},
            new Students(){ Id=39, Age=131, Name="这是变化后的集合"},
            new Students(){ Id=49, Age=141, Name="这是变化后的集合"}
            };
            viewModel.StudentList[2].Name = "这是一个属性改变";
        }
    }

    public class Students : INotifyPropertyChanged
    {
        string _name;
        public int Id { get; set; }
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
        public int Age { get; set; }
        protected internal virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }



    public class ViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<Students> studentList;
        public ObservableCollection<Students> StudentList
        {
            get { return this.studentList; }
            set
            {
                if (this.studentList != value)
                {
                    this.studentList = value;
                    OnPropertyChanged("StudentList");
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值