The use of ObservableCollection in two way binding notification mechanism in WPF
</div>
The observablecollection < T > class in msdn represents a dynamic data collection that provides notifications when items are added, removed, or the entire list is refreshed.
In many cases, the data used is a collection of objects. For example, a common scenario in data binding is to use ItemsControl (for example ListBox,ListView Or TreeView )To display a collection of records.
Can be implemented by enumeration IEnumerable Any collection of interfaces. However, to set a dynamic binding so that an insert or delete operation in a collection can automatically update the UI, the collection must implement INotifyCollectionChanged Interface. This interface is exposed CollectionChanged Event that should be raised whenever the underlying collection changes.
WPF provides the observablecollection < T > class, which is the implementation of INotifyCollectionChanged The built-in implementation of the data collection of the interface.
In many cases, the data we use is just fields or properties. At this time, we need to implement the INotifyPropertyChanged interface for these fields or properties, which will provide a notification mechanism as long as the fields or properties change.
Observablecollection < T > implementation
Front desk xmal
<Window x:Class="WpfApplication1.WindowObservable" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window8" Height="356" Width="471"> <Grid> <StackPanel Height="295" HorizontalAlignment="Left" Margin="10,10,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="427"> < TextBlock height = "23" name = "textblock1" text = "student number:" / > <TextBox Height="23" Name="txtStudentId" Width="301" HorizontalAlignment="Left"/> < TextBlock height = "23" name = "textblock2" text = "student list:" / > <ListBox Height="156" Name="lbStudent" Width="305" HorizontalAlignment="Left"> <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>
Background cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Collections.ObjectModel; using System.ComponentModel;
namespace WpfApplication1
{
public partial class WindowObservable : Window
{
ObservableCollection<Students> infos = 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"}
};
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> WindowObservable() { InitializeComponent(); </span><span style="color: #0000ff;">this</span>.lbStudent.ItemsSource =<span style="color: #000000;"> infos; </span><span style="color: #0000ff;">this</span>.txtStudentId.SetBinding(TextBox.TextProperty, <span style="color: #0000ff;">new</span> Binding(<span style="color: #800000;">"</span><span style="color: #800000;">SelectedItem.Id</span><span style="color: #800000;">"</span>) { Source =<span style="color: #000000;"> lbStudent }); } </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> button1_Click(<span style="color: #0000ff;">object</span><span style="color: #000000;"> sender, RoutedEventArgs e) { infos[</span><span style="color: #800080;">1</span>] = <span style="color: #0000ff;">new</span> Students() { Id = <span style="color: #800080;">4</span>, Age = <span style="color: #800080;">14</span>, Name = <span style="color: #800000;">"</span><span style="color: #800000;">This is a collective change</span><span style="color: #800000;">"</span><span style="color: #000000;"> }; infos[</span><span style="color: #800080;">2</span>].Name = <span style="color: #800000;">"</span><span style="color: #800000;">It's a property change</span><span style="color: #800000;">"</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Students { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> Id { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Name { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> Age { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; } } }
}
In this example, we decorated the Students data object with observablecollection < T >. So we see when we click. When we click, only the change of the whole object of the student causes the background notification mechanism.
INotifyPropertyChanged implementation
INotifyPropertyChanged notifies the client that a property value has changed. When the element attribute value changes, the background model is notified
The foreground code remains the same. Let's let the background Students Model implement the INotifyPropertyChanged interface.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Collections.ObjectModel; using System.ComponentModel;
namespace WpfApplication1
{
public partial class WindowObservable : Window
{
ObservableCollection<Students> infos = 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"}
};
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> WindowObservable() { InitializeComponent(); </span><span style="color: #0000ff;">this</span>.lbStudent.ItemsSource =<span style="color: #000000;"> infos; </span><span style="color: #0000ff;">this</span>.txtStudentId.SetBinding(TextBox.TextProperty, <span style="color: #0000ff;">new</span> Binding(<span style="color: #800000;">"</span><span style="color: #800000;">SelectedItem.Id</span><span style="color: #800000;">"</span>) { Source =<span style="color: #000000;"> lbStudent }); } </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> button1_Click(<span style="color: #0000ff;">object</span><span style="color: #000000;"> sender, RoutedEventArgs e) { infos[</span><span style="color: #800080;">1</span>] = <span style="color: #0000ff;">new</span> Students() { Id = <span style="color: #800080;">4</span>, Age = <span style="color: #800080;">14</span>, Name = <span style="color: #800000;">"</span><span style="color: #800000;">This is a collective change</span><span style="color: #800000;">"</span><span style="color: #000000;"> }; infos[</span><span style="color: #800080;">2</span>].Name = <span style="color: #800000;">"</span><span style="color: #800000;">It's a property change</span><span style="color: #800000;">"</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Students : INotifyPropertyChanged { </span><span style="color: #0000ff;">string</span><span style="color: #000000;"> _name; </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> Id { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span><span style="color: #000000;"> Name { </span><span style="color: #0000ff;">get</span> { <span style="color: #0000ff;">return</span><span style="color: #000000;"> _name; } </span><span style="color: #0000ff;">set</span> { _name = value; OnPropertyChanged(<span style="color: #800000;">"</span><span style="color: #800000;">Name</span><span style="color: #800000;">"</span><span style="color: #000000;">); } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> Age { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">internal</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnPropertyChanged(<span style="color: #0000ff;">string</span><span style="color: #000000;"> propertyName) { </span><span style="color: #0000ff;">if</span> (PropertyChanged != <span style="color: #0000ff;">null</span><span style="color: #000000;">) PropertyChanged(</span><span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span><span style="color: #000000;"> PropertyChangedEventArgs(propertyName)); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span><span style="color: #000000;"> PropertyChangedEventHandler PropertyChanged;</span><span style="color: #000000;"> } }
}
At this point, if we run the code again, we will find that
Using DataContext to set context for page objects
Both sets and objects have changed. So far. Our whole background notification can perfectly monitor any object changes.
But now there is another problem. If we assign a new set of data to infos in the click event. as follows
private void button1_Click(object sender, RoutedEventArgs e) { Infos [1] = new students() {id = 4, age = 14, name = "this is a set change"}; infos[2].Name = "this is a property change";
infos = new ObservableCollection<Students>() { New students() {id = 1, age = 11, name = "this is the changed set"}, New students() {id = 2, age = 12, name = "this is the changed set"}, New students() {id = 3, age = 13, name = "this is the changed set"}, New students() {id = 4, age = 14, name = "this is the changed set"} };
}
You will find that the data has not changed. Why? We clearly implement the observablecollection < T > type. This is because the address change of infos does not implement the notification mechanism. When we assign a new object to infos, the address of infos changes. So when the data in the collection changes, the data after infos changes will participate in binding. At this time, we can realize the change notification of data items through DataContext. We add a ViewModel class to implement the INotifyPropertyChanged interface
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) { PropertyChangedEventHandler handler = this.PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }
The windowsObservable class is modified as follows
public partial class WindowObservable : Window { ViewModel viewModel = new ViewModel(); public WindowObservable() { 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; } private void button1_Click(object sender, RoutedEventArgs e) { ViewModel. Studentlist [1] = new students() {id = 4, age = 14, name = "this is a set change"}; viewModel.StudentList = new ObservableCollection<Students>() { New students() {id = 19, age = 111, name = "this is the changed geometry"}, New students() {id = 29, age = 121, name = "this is the changed geometry"}, New students() {id = 39, age = 131, name = "this is the changed geometry"}, New students() {id = 49, age = 141, name = "this is the changed geometry"} }; viewModel.StudentList[2].Name = "this is a property change"; } }
We set the following binding for xaml listbox
ItemsSource="{Binding StudentList, Mode=TwoWay}"
Running the program, we find that the changes of the collection will also be notified to the foreground.
Code reference: http://blog.csdn.net/fwj380891124/article/details/8194190
Address: http://www.cnblogs.com/santian/p/4366832.html
Blog address: http://www.cnblogs.com/santian/
<div id="blog_post_info">
<div class="clear"></div> <div id="post_next_prev"> <a href="https://Www.cnblogs.com/santian/p/4362679.html "class =" p_n_p_prefix "></a> <br> <a href="https://Www.cnblogs.com/santian/p/4372667.html "class =" p_n_p_prefix "></a>
FeedBack:
<div class="feedbackItem"> <div class="feedbackListTitle">
2017-12-27 19:08
|
<a id="a_comment_author_3875567" href="https://Www.cnblogs.com/shinexyt/ "target =" _blank "> 17 ℃ blue</a>
</div> <div class="feedbackItem"> <div class="feedbackListTitle">
2018-01-10 16:21
|
<a id="a_comment_author_3886189" href="https://www.cnblogs.com/liubo1/" target="_blank">liubo1</a>
</div> <div class="feedbackItem"> <div class="feedbackListTitle">
2018-02-27 17:41
|
<a id="a_comment_author_3912138" href="https://Www.cnblogs.com/tangyun2016xi/ "target =" blank "> oath of the sea</a>
</div> <div class="feedbackItem"> <div class="feedbackListTitle">
2019-01-18 09:55
|
<a id="a_comment_author_4165597" href="https://Home. Cnblogs. COM / U / 1508414 / "target =" _blank "> Korean star</a>
</div> <div class="feedbackItem"> <div class="feedbackListTitle">
<span id="comment-maxId" style="display:none">4235220</span> <span id="comment-maxDate" style="display:none">2019/4/19 4 p.m.:02:47</span>
2019-04-19 16:02
|
<a id="a_comment_author_4235220" href="https://www.cnblogs.com/zlyxm/" target="_blank">zlyxm</a>
</div>
[recommended] 58 home technology VP Shen Jian's architect growth path
[recommended] 20 must see free Alibaba boutique e-books
[recommended] open download! Youku technical script behind the blockbuster of "twelve hours of Chang'an" was first released
<div id="google_ads_iframe_/1090369/C2_0__container__" style="border: 0pt none;"><iframe id="google_ads_iframe_/1090369/C2_0" title="3rd party ad content" name="google_ads_iframe_/1090369/C2_0" width="468" height="60" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" srcdoc="" style="border: 0px; vertical-align: bottom;" data-google-container-id="2" data-load-complete="true"></iframe></div></div> </div> <div id="under_post_kb">
· In the past five years, China's mobile phone manufacturers have been re established: why didn't Huawei Yu Chengdong's previous prediction come true?
· Zhou Yahui sold the world's largest same-sex social platform, but made another 3.2 billion
· After returning to work, the shared bicycle is ushering in the second spring, but the opportunity to turn over is no longer an ofo
· China Unicom promotes the mixed reform, starts the reform of operation organization system, and takes the road of Internet transformation
· Part time "car model", new AI job of Hengdian group performance
» More news