WPF – Data Binding

Data binding is the process that establishes a connection between the application UI and business logic. Where application UI (View) has DataContext property and View Controls properties are bind to the CLR properties of the object assigned to DataContext. The object assigned to DataContext is a Model or ViewModel (contains view logic).

DataBinding subscribes to INotifyPropertyChanged interface PropertyChanged event. When DataContext object property changed, it notify binding to update Control on the View.

INotifyPropertyChanged interface Implementation:


    public class Base : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChange([CallerMemberName] string name = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }

Example:

ViewModel:


    public class Displayable : Base
    {
        public string Name { get; set; }
    }

    public class ViewModel : Displayable
    {

        public ViewModel(PatientService ps)
        {
            CurrentPatientService = ps;
        }

        public PatientService CurrentPatientService { get; set; }
    }

    public class PatientViewModel : ViewModel
    {
        public PatientViewModel(PatientService ps)
            : base(ps)
        {
            Name = "Patients";

            // Load on startup
            CurrentPatientService = ps;
            Patients = CurrentPatientService.Patients;
        }

        private ObservableCollection patients;

        public ObservableCollection Patients
        {
            get
            {
                return patients;
            }
            set
            {
                if (patients != value)
                {
                    patients = value;
                    OnPropertyChange();
                }
            }
        }

        private Patient selectedPatient;
        public Patient SelectedPatient
        {
            get
            {
                return selectedPatient;
            }

            set
            {
                if (selectedPatient != value)
                {
                    selectedPatient = value;
                    DiagnosisProperty = new DiagnosisDisplay(selectedPatient.PatientDiagnosis);
                    OnPropertyChange("SelectedPatient");
                }
            }
        }

        private DiagnosisDisplay diagnosisProperty;

        public DiagnosisDisplay DiagnosisProperty
        {
            get { return diagnosisProperty; }
            set
            {
                diagnosisProperty = value;
                OnPropertyChange();
            }
        }
}

XAML:

<Grid.Resources>
       <DataTemplate DataType="{x:Type mod:Patient}">
           <StackPanel>
               <StackPanel Orientation="Horizontal">
                   <Label Content="Name" />
                   <Label Content="{Binding Name}" />
               </StackPanel>
               <StackPanel Orientation="Horizontal">
                   <Label Content="City" />
                   <Label Content="{Binding City}" />
               </StackPanel>
           </StackPanel>
       </DataTemplate>
</Grid.Resources>

<Grid>
   <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto"/>
      <ColumnDefinition Width="5"/>
      <ColumnDefinition Width="*"/>
      <ColumnDefinition Width="5"/>
      <ColumnDefinition Width="Auto"/>
   </Grid.ColumnDefinitions>
   <StackPanel>
       <Button MinHeight="20" Height="20" Grid.Column="0" HorizontalAlignment="Stretch" Command="{Binding Load}">Load</Button>
       <ListBox x:Name="mylist" Grid.Column="0 ItemsSource="{Binding Patients}" ItemTemplate="{StaticResource listDataTemplate}" MinWidth="200" />
   </StackPanel>
   <GridSplitter Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Stretch" Width="5" Background="Gray" />
   <StackPanel Grid.Column="2" >
     <Label MinHeight="100" Height="100" Content="{Binding Error}"/>
     <ContentPresenter Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" Content="{Binding SelectedPatient.PatientDiagnosis}"  />
    </StackPanel>
    <GridSplitter Grid.Column="3" Width="5" HorizontalAlignment="Center"  VerticalAlignment="Stretch" Background="Gray"/>
    <ContentPresenter Grid.Column="4" Margin="10" Width="200" VerticalAlignment="Stretch" Content="{Binding DiagnosisProperty}"/>
</Grid>

Alternative of INotifyPropertyChanged interface is IObservable. IObservable also has the extra benefits of having the concept of a sequence termination via OnError or OnCompleted.

Leave a Reply

Your e-mail address will not be published. Required fields are marked *