1

I have a usercontrol (a label and a textbox. I would like to bind the Text of the user control to the property Name from an DTO class Employee ( Employee.Name) where binding is set in the mainwindow, outside of the usercontrol. This is my UserControl ( look at the controls label and text)

<UserControl x:Class="TestCompany.controls.textEdit"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:TestCompany.controls"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

<Grid >
    <Grid.RowDefinitions>
        <RowDefinition Height="60" />
        <RowDefinition MinHeight="50" />
    </Grid.RowDefinitions>
    <Label Name="label" Content="{Binding Caption}" Grid.Row="0" FontSize="35" FontWeight="Light"/>
    <TextBox Name="textbox" Text="{Binding Text}" Grid.Row="1" FontSize="33" Background="White"  />
</Grid>

Caption is the title of the control and Text displays the value

And here is the code behind

public string Caption
    {
        get
        {
            return (string)GetValue(CaptionProperty);
        }

        set
        {
            SetValue(CaptionProperty, value);                
        }
    }

    public static DependencyProperty CaptionProperty =
        DependencyProperty.Register("Caption", typeof(string), typeof(textEdit), null);


    public string Text
    {
        get
        {
            return (string)GetValue(TextProperty);                
        }

        set
        {
            SetValue(TextProperty, value);                
        }
    }

    public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(textEdit), null);

Now in the main window, this is how I use my custom control

<controls:textEdit Caption="Name" Text="{Binding Name}" Grid.Column="0" HorizontalAlignment="Stretch" Margin="0,0,20,0" />

Then in the mainwindow, from the list of Employees, I take the selected one and I assign it to the context

this.DataContext = EmployeeObject; // Name = "Joe"

But the Text property of the usercontrol does not display "Joe". Even the setter of the property is never called. The weird this is that if within the constructor of my usercontrol I don't assign UserControl.Datacontext to this

DataContext = this; // within the constructor of UserControl

then even the Label control is empty (the label control is linked to the Caption dependency property). I have looked at countless similar issues on stackOverflow and else where. ( RelativeSource Self etc...). Nothing works...The Text property of my user control does not display value from the Datacontext set in the mainwindow...

Any help would be greatly appreciated

TheSoul
  • 4,906
  • 13
  • 44
  • 74
  • Possible duplicate of [Binding to UserControl DependencyProperty](http://stackoverflow.com/questions/16985382/binding-to-usercontrol-dependencyproperty); read also comments about DataContext under accepted answer – ASh Jun 03 '16 at 09:31
  • Thanks for the suggestion. I applied the solution provided there. The text correctly display the value. But the label is now empty – TheSoul Jun 03 '16 at 09:37
  • Can you include the code when you created the EmployeeObject? – tgpdyk Jun 03 '16 at 09:38
  • It is a very simple code: var EmployeeObject = DAL.fetch("empID"); fecth is a call to backend and it returns a Emp object with specified empID. classic stuff. – TheSoul Jun 03 '16 at 09:39
  • I just want to make sure that the object has its property set before it was assigned and implementing INPC. Is it? – tgpdyk Jun 03 '16 at 09:41
  • Yes Name has its value correctly set. I can see it while debugging – TheSoul Jun 03 '16 at 09:41
  • You see, Text property is supposed to take its value from EmployeeObject.Name. So DataContext of UserControl must be correctly set. But Caption property (the label control) has its value hardcoded in the mainwindow (see above in the question --> Caption="Name" where I insert the usercontrol) – TheSoul Jun 03 '16 at 09:45

1 Answers1

1

You need to set the DataContext of the UserControl to that of your main window, and the DataContextof the Grid to the UserControl. That means that when the UserControlis looking for its data, it looks in the DataContext it inherits from MainWindow, but when your Grid looks for its data, it looks inside the UserControl. You do it like this:

<UserControl ... 
     d:DesignHeight="300" d:DesignWidth="300"
     x:Name="ThisControl">

<Grid DataContext="{Binding ElementName=ThisControl}">
...

See http://blog.scottlogic.com/2012/02/06/a-simple-pattern-for-creating-re-useable-usercontrols-in-wpf-silverlight.html.

PScr
  • 449
  • 2
  • 11
  • Thanks. I have done what you said. I defined a DataContextin the Grid, within the UserControl. Still the Text correctly binds. But the label is still empty. – TheSoul Jun 03 '16 at 09:51
  • Great. That article was what really gave me a way in to understanding DataContext. – PScr Jun 03 '16 at 10:23