14

The line below works for the TextBox DP Text, where CellNo is a property of a class which derives from INotifyPropertychanged. So here when I change the CellNo the Text will be updated and When I change the CellNo the Text will be updated. This will work fine.

Text="{Binding Path = CellNo, Mode=TwoWay,  UpdateSourceTrigger=PropertyChanged}"

I have create a user control which contain only one TextBox. I have defined one DP name CellValue as below:

public string CellValue
    {
        get { return (string)GetValue(CellValueProperty); }
        set { SetValue(CellValueProperty, value); }
    }

    // Using a DependencyProperty as the backing store for LimitValue.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CellValueProperty =
        DependencyProperty.Register("CellValue", typeof(string), typeof(control), new FrameworkPropertyMetadata
        {
            BindsTwoWayByDefault = true,
        });

Now when I use this user control in any dialog and do the same binding as above, the Target ( TextBox inside User control) is NOT updating.

 <local:control
        x:Name="control" 
        CellValue="{Binding Path = CellNo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">

Also inside user control I have binded the Text Property of TextBox to CellValue DP.

Inside User control

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

I want when the CellValue changes the TextBox Text should also be updated, but with the above appoach it remains blank.

Ashish Ashu
  • 14,169
  • 37
  • 86
  • 117
  • 1
    Do you see any data binding errors in the output window ? Is the DataCcontext property of the Usercontrol set such that the TextBox binding is valid ? – Gishu Nov 15 '10 at 07:16
  • Yes, the data context of the user control is the same as of parent control. Also while debugging, I verified that the dependency property ( CellValue ) is updated inside the user control, but it dosen't update the Text property of TexBox. Do I have to implement the Property changed callback ? – Ashish Ashu Nov 15 '10 at 08:15

1 Answers1

18

This code

<local:control x:Name="control"  
               CellValue="{Binding Path=CellNo,
                                   Mode=TwoWay,
                                   UpdateSourceTrigger=PropertyChanged}">

is trying to bind against the Property CellNo of the UserControl. Add RelativeSource or ElementName and it'll work.

<local:control x:Name="control"  
               CellValue="{Binding Path=CellNo,
                                   RelativeSource={RelativeSource AncestorType={x:Type Window}}, 
                                   Mode=TwoWay,
                                   UpdateSourceTrigger=PropertyChanged}">

<local:control x:Name="control"  
               CellValue="{Binding Path=CellNo,
                                   ElementName=myWindow,
                                   Mode=TwoWay,
                                   UpdateSourceTrigger=PropertyChanged}">

You may also need to set the the DataContext of control to itself

public control()
{
    InitializeComponent();
    this.DataContext = this;
    //...
}

Update

You can download a sample application of this here.

Otherwise, here's my full sample code.

MainWindow.xaml

<Window x:Class="DependencyPropertyInsideUserControl.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DependencyPropertyInsideUserControl"
        Title="MainWindow" Height="350" Width="525"
        Name="myWindow">
    <Grid>
        <local:control x:Name="control"
                       CellValue="{Binding Path = CellNo, Mode=TwoWay, ElementName=myWindow, UpdateSourceTrigger=PropertyChanged}"/>
            <Button Content="Update CellNo" Height="23" HorizontalAlignment="Left" Margin="185,149,0,0" Name="button1" VerticalAlignment="Top" Width="94" Click="button1_Click" />
    </Grid>
</Window>

Mainwindow.xaml.cs

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
        CellNo = "Hello";
    }
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        CellNo = "Hi";
    }
    private string m_cellNo;
    public string CellNo
    {
        get
        {
            return m_cellNo;
        }
        set
        {
            m_cellNo = value;
            OnPropertyChanged("CellNo");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

control.xaml

<UserControl x:Class="DependencyPropertyInsideUserControl.control"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBox Text="{Binding Path = CellValue}" 
                 Name="textBox2" />
    </Grid>
</UserControl>

control.xaml.cs

public partial class control : UserControl
{
    public string CellValue
    {
        get { return (string)GetValue(CellValueProperty); }
        set { SetValue(CellValueProperty, value); }
    }
    // Using a DependencyProperty as the backing store for LimitValue.  This enables animation, styling, binding, etc...    
    public static readonly DependencyProperty CellValueProperty =
        DependencyProperty.Register("CellValue", typeof(string), typeof(control), new FrameworkPropertyMetadata
        {
            BindsTwoWayByDefault = true,
        });
    public control()
    {
        InitializeComponent();
        this.DataContext = this;
        CellValue = "Test";
    }
}
Fredrik Hedblad
  • 83,499
  • 23
  • 264
  • 266
  • 3
    I had to use "Path=DataContext.CellNo" for the binding in the Window to work for me. – Dan Vogel Dec 30 '13 at 22:06
  • Is it possible that you can see the DefaultValue in the UserControl on design time?? – Dominic Jonas Nov 08 '16 at 09:53
  • In my case, using MVVM pattern on the MainWindow, I had to set `textBox2.DataContext = this;` instead of `this.DataContext = this` in the control code otherwise it would break the MVVM binding. – CowWarrior Aug 05 '22 at 13:58