Edward Tanguay
Edward Tanguay

Reputation: 193372

How to get WPF DataBinding-to-an-object to work

In the following example I bind the XAML to a static object via ObjectDataProvider. When the user changes information, I want it to automatically reflect in the XAML.

What I don't understand is:

How to I get THERE from HERE:

XAML:

<Window x:Class="TestBinding99382.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestBinding99382"
    Title="Window1" Height="300" Width="300">

    <Window.Resources>
        <ObjectDataProvider 
             x:Key="DataSourceCustomer" 
             ObjectType="{x:Type local:Customer}" MethodName="GetCustomer"/>

        <Style x:Key="DataRowStyle" TargetType="StackPanel">
            <Setter Property="Orientation" Value="Horizontal"/>
            <Setter Property="VerticalAlignment" Value="Top"/>
            <Setter Property="Margin" Value="0 10 0 0"/>
            <Setter Property="DataContext" 
                    Value="{StaticResource DataSourceCustomer}"/>
            <Setter Property="DockPanel.Dock" Value="Top"/>
        </Style>
    </Window.Resources>

    <DockPanel>
        <StackPanel DockPanel.Dock="Top" 
                    DataContext="{StaticResource DataSourceCustomer}" 
                    Orientation="Horizontal">
            <TextBlock Text="{Binding Path=FirstName}"/>
            <TextBlock Text=" "/>
            <TextBlock Text="{Binding Path=LastName}"/>
            <TextBlock Text=" ("/>
            <TextBlock Text="{Binding Path=FullName}" FontWeight="Bold"/>
            <TextBlock Text=")"/>
        </StackPanel>

        <StackPanel Style="{StaticResource DataRowStyle}">
            <TextBlock Text="First Name:"/>
            <TextBox Text="{Binding Path=FirstName}" 
                      Width="200" Margin="3 0 0 0"/>
        </StackPanel>

        <StackPanel Style="{StaticResource DataRowStyle}">
            <TextBlock Text="Last Name:"/>
            <TextBox Text="{Binding Path=LastName}" 
                     Width="200" Margin="3 0 0 0"/>
        </StackPanel>

        <StackPanel Style="{StaticResource DataRowStyle}">
            <Button Content="Save Changes" Click="Button_Click"/>
        </StackPanel>

    </DockPanel>
</Window>

Code Behind:

using System.Windows;
using System.ComponentModel;
using System;

namespace TestBinding99382
{
    public partial class Window1 : Window
    {
        private Customer _customer;

        public Window1()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //I want to edit the _customer object here
            //and have it my changes automatically reflect in my XAML
            //via the INotifyPropertyChanged inheritance.
        }
    }

    public class Customer : INotifyPropertyChanged
    {
        private string _firstName;
        private string _lastName;

        public string FirstName
        {
            get
            {
                return _firstName;
            }

            set
            {
                _firstName = value;
                this.RaisePropertyChanged("FirstName");
                this.RaisePropertyChanged("FullName");
            }
        }

        public string LastName
        {
            get
            {
                return _lastName;
            }

            set
            {
                _lastName = value;
                this.RaisePropertyChanged("LastName");
                this.RaisePropertyChanged("FullName");
            }

        }

        public string FullName
        {
            get
            {
                return String.Format("{0} {1}", _firstName, _lastName);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }


        public static Customer GetCustomer()
        {
            return new Customer { FirstName = "Jim", LastName = "Smith" };
        }

    }
}

Upvotes: 2

Views: 4287

Answers (1)

Wallstreet Programmer
Wallstreet Programmer

Reputation: 9677

in the click event, how do I access the "object that is being edited"

You can access a resource in the behind code using FindResource method, see below.

private void Button_Click(object sender, RoutedEventArgs e)
{
    ObjectDataProvider objectDataProvider 
        = FindResource("DataSourceCustomer") as ObjectDataProvider;
    _customer = objectDataProvider.Data as Customer;
}

For your other questions:

What is perpetuate? You do not have to create a singleton to databind in WPF if that is your question.

eventually of course I want the data to be retrieved from a model which reads an XML file or web service, and I want of course my ViewModel to check my model every second or so to see if the data has changed and reflect this on the XAML.

WPF databinding will automatically update your view of you use an INotifyPropertyChanged object. Unless for performance reasons you only want to update your view every second or so just stick to normal databinding.

Upvotes: 1

Related Questions