views:

894

answers:

1

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 do I perpetuate the object? do I have to create a singleton? in the click event, how do I access the "object that is being edited"
  • 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.

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" };
        }

    }
}
+1  A: 

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.

Wallstreet Programmer
I want to get an example working in which a model's data continually changes and those changes are represented in XAML, here is an example that I want to get to work where the model has the current DateTime which should be reflected in XAML: http://stackoverflow.com/questions/851595/why-is-inotifychanged-not-updating-the-variables-in-xaml
Edward Tanguay
I was able to get this example working the way I wanted to using a singleton method here: http://stackoverflow.com/questions/852441/fat-models-skinny-viewmodels-and-dumb-views-the-best-mvvm-approach
Edward Tanguay