1

I've read the online document about data binding but still couldn't make it work. I simply want to understand data binding and do things the way it should.

Here is my code in my UI.xaml.cs

namespace mynamespace
{
   class Customer
   {
     private string _name = "TEST";
     public string Name
     {
        get { return this._name; }
        set { this._name = value; }
     }
   }

   public partial class UI: UserControl
   {
       public UI()
       {
           InitializeComponent();
           Customer c = new Customer();
           this.DataContext = c;
       }
   }
}

The binding code (target is a textbox) looks like this:

<TextBox Name="MyTextBox" Text="{Binding Path=Name}" />

I expect the textbox will show TEST, but it doesn't. There is nothing in the textbox. The documentation (Data Binding Overview, Binding Declarations Overview, and Binding Sources Overview) is not very clear to me.

This is the error message from the Output window:

BindingExpression path error: 'Name' property not found on 'object' ''ConfigurationSettings' (HashCode=36012562)'. BindingExpression:Path=Name; DataItem='ConfigurationSettings' (HashCode=36012562); target element is 'TextBox' (Name='MyTextBox'); target property is 'Text' (type 'String')
Unplug
  • 709
  • 10
  • 27
  • 4
    Why the Window class' constructor is named UI? I think the code can't compile. – Mario Vernari Sep 09 '13 at 04:49
  • 2
    Customer class needs to be public? – JumpingJezza Sep 09 '13 at 04:50
  • [This answer](http://stackoverflow.com/questions/7262137/what-is-datacontext-for) may be helpful. – Nzc Sep 09 '13 at 07:59
  • What does the output windows say? – Daniel Sep 09 '13 at 08:30
  • The code won't compile in it's current form unless you add a return type to the UI function, in which case it will compile but won't work (the constructor will be the default empty constructor). Change `UI` to `Window` in order to make the UI function a constructor for the class – Charleh Sep 09 '13 at 08:53
  • @JumpingJezza making Customer class public alone doesn't solve the problem. I am absorbing the comments one by one, so your suggestion may need to combine with others. I just don't know yet. – Unplug Sep 09 '13 at 15:41
  • @Daniel The textbox I bind to the Customer class was empty, while I expected TEST in it. – Unplug Sep 09 '13 at 15:47

4 Answers4

1

I am such an idiot! I have two constructors, one default and one parametrized constructor. I was calling the parametrized constructor. After I move the code:

       Customer c = new Customer();
       this.DataContext = c;

to the parametrized constructor, it all worked.

Thank you all for helping and sorry about this stupid mistake.

Unplug
  • 709
  • 10
  • 27
0

Mario is right, so you code should look like this:

namespace mynamespace
{
   class Customer
   {
     private string _name = "TEST";
     public string Name
     {
        get { return this._name; }
        set { this._name = value; }
     }
   }

   public partial class Window : UserControl
   {
       public Window()
       {
           InitializeComponent();
           Customer c = new Customer();
           this.DataContext = c;
       }
   }
}
Chevul Ervin
  • 863
  • 5
  • 9
  • Mario was right, I was cutting out unrelated code. We source was correct and it did compile. (I also edit the question so it's consistent) – Unplug Sep 09 '13 at 14:47
0

If the Customer c is the DataContext shouldnt it be:

 <TextBox Name="MyTextBox" Text="{Binding Name}" />
Filip
  • 656
  • 4
  • 8
0

Try implementing the INotifyPropertyChanged interface and override the ToString() in your Customer class:

public class Customer : INotifyPropertyChanged
{
    private string _name = "TEST";
    public string Name
    {
        get { return _name; }
        set { _name = value; NotifyPropertyChanged("Name"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public override string ToString()
    {
        return Name;
    }
}

Then if that still doesn't work, try setting the Name property with the value in the Window constructor, rather than the private field internally:

public Window()
{
    InitializeComponent();
    Customer c = new Customer() { Name = "TEST" };
    this.DataContext = c;
}
Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • 1
    I thought implement INotifyPropertyChanged is when you want to update target and/or source on the fly. Since the Name was set initially, I should at least see TEST. I did implement INotifyPropertyChanged like you suggested, but still no go. – Unplug Sep 09 '13 at 16:01
  • The `INotifyPropertyChanged` interface is used to update the UI and/or the data sources of *any* changes... you had better get used to using it, if you want to write WPF. :) – Sheridan Sep 09 '13 at 16:04