Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
482 views
in Technique[技术] by (71.8m points)

c# - Why use INotifyPropertyChanged with bindings in WPF?

I've notived that practically every example I find on the internet about bindings has a class (which binds to another property) that inherits the INotifyPropertyChanged interface and uses a method in the set part of the class' property.

I've tried removing that part from the binding example and it worked the same as it would with the method.

Here's the example. I've altered it so it would be a TwoWay bindingmode and show the changed property in a messagebox.

I did that just to play around a little bit with bindings, but now I really don't know why that interface is used

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="40"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="30"/>
        </Grid.ColumnDefinitions>
        <Button Grid.Row="5" Grid.Column="5" Name="btnBinding" Click="btnBinding_Click" Width="100" Height="30">
            <Grid HorizontalAlignment="Left" VerticalAlignment="Center">
                <Grid.RowDefinitions>
                    <RowDefinition Height="25"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition Width="50"/>
                </Grid.ColumnDefinitions>
                <TextBox Name="txtBinding" Width="30" Height="25" HorizontalAlignment="Left"/> 
                <Label Grid.Column="1" Content="Bind"/>
            </Grid>
        </Button>
        <Button Grid.Column="5" Grid.Row="6" Name="btnMessage" Click="btnMessage_Click" Content="MessageBox"/>
        <Button Grid.Column="5" Grid.Row="4" Name="btnChangeproperty" Click="btnChangeproperty_Click" Content="Change Property"/>
    </Grid>
</Window>

Main.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.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Binding bind;
        MyData mydata;
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnBinding_Click(object sender, RoutedEventArgs e)
        {
            mydata = new MyData("T");
            bind = new Binding("MyDataProperty")
            {
                Source = mydata,
                Mode = BindingMode.TwoWay
            };

            txtBinding.SetBinding(TextBox.TextProperty, bind);
        }

        private void btnMessage_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(mydata.MyDataProperty);
        }

        private void btnChangeproperty_Click(object sender, RoutedEventArgs e)
        {
            mydata.MyDataProperty = "New Binding";
        }
    }
}

MyData class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace WpfApplication1
{
    public class MyData 
    {
        private string myDataProperty;

        public MyData() { }

        public MyData(DateTime dateTime)
        {
            myDataProperty = "Last bound time was " + dateTime.ToLongTimeString();
        }

        public MyData(string teste)
        {
            myDataProperty = teste;
        }

        public String MyDataProperty
        {
            get { return myDataProperty; }
            set
            {
                myDataProperty = value;
                OnPropertyChanged("MyDataProperty");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string info)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(info));
            }
        }
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You don't need INotifyPropertyChanged if you only intend to use the binding to write to the property (as you have found out), but you do need it so that you can tell that someone else wrote to the property and update the displayed value accordingly.

To see what I 'm talking about, add a button to your window that when clicked directly changes the value of the bound property (not the corresponding attribute of the UI element bound to that property). With INotifyPropertyChanged, you will see the UI updating itself to the new value when you click the button; without it, the UI will still show the "old" value.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...