This is probably not a rocket science question, so forgive me for being a newcomer!
I have a UserControl that is for setting the name of a person (simple for test purposes).
PersonNameControl.xaml:
<UserControl x:Class="BindingPropagationTest.Controls.PersonNameControl"
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" Width="120" Height="23" Margin="0,0,0,0"
>
<TextBox Name="TextBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</UserControl>
and as you can see, it contains a TextBox that is the “real” textbox. The code behind looks like this.
PersonNameControl.xaml.cs:
using System.Windows.Controls;
using System.Windows;
using System.Diagnostics;
namespace BindingPropagationTest.Controls
{
public partial class PersonNameControl : UserControl
{
public static DependencyProperty nameProperty
= DependencyProperty.Register("PersonName", typeof(string), typeof(PersonNameControl));
public string PersonName
{
get
{
Debug.WriteLine("get PersonNameControl.PersonName = " + TextBox.Text);
return TextBox.Text;
}
set
{
Debug.WriteLine("set PersonNameControl.PersonName = " + value);
TextBox.Text = value;
}
}
public PersonNameControl()
{
InitializeComponent();
}
}
}
I use the usercontrol in MainWindow.xaml:
<Window x:Class="BindingPropagationTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:BindingPropagationTest.Controls"
xmlns:items="clr-namespace:BindingPropagationTest.ComboBoxItems"
Title="Testing binding in UserControl"
Width="179" Height="310">
<Canvas Height="241" Width="144">
<Label Canvas.Left="11" Canvas.Top="10" Content="Name" Height="28" Padding="0" />
<my:PersonNameControl x:Name="nameControl"
Width="120" Height="23"
HorizontalAlignment="Left" VerticalAlignment="Top"
PersonName="{Binding name}"
Canvas.Left="11" Canvas.Top="28" />
<Label Canvas.Left="11" Canvas.Top="57" Content="Address" Height="28" Padding="0" />
<TextBox Canvas.Left="11" Canvas.Top="75" Width="120" Text="{Binding address}"></TextBox>
<Label Canvas.Left="11" Canvas.Top="103" Content="Age" Height="28" Padding="0" />
<TextBox Canvas.Left="11" Canvas.Top="122" Height="23" Name="textBox1" Width="120" Text="{Binding age}" />
<ComboBox Canvas.Left="11" Canvas.Top="173" Height="23"
Name="comboBox1" Width="120" SelectionChanged="comboBox1_SelectionChanged">
<items:PersonComboBoxItem age="41" name="Donald Knuth" address="18 Donut Street" Height="23" />
<items:PersonComboBoxItem age="23" name="Vladimir Putin" address="15 Foo Street" Height="23" />
<items:PersonComboBoxItem age="32" name="Mike Hammer" address="10 Downing Street" Height="23" />
</ComboBox>
</Canvas>
</Window>
together with some normal TextBoxes as you can see.
In the code behind for MainWindow
MainWindow.xaml.cs:
using System.Windows;
using System.Windows.Controls;
using BindingPropagationTest.ComboBoxItems;
namespace BindingPropagationTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Person();
}
private void comboBox1_SelectionChanged
(object sender, SelectionChangedEventArgs e)
{
updateForm();
}
private void updateForm()
{
var item = (PersonComboBoxItem)comboBox1.SelectedItem;
DataContext = new Person()
{ age = item.age, name = item.name, address = item.address };
}
}
}
you see that I set DataContext to a “person”.
Person.cs:
namespace BindingPropagationTest
{
public class Person
{
public string name {get; set; }
public int age { get; set; }
public string address { get; set; }
}
}
and as you notice I have invented an own ComboBoxItem like this.
PersonComboBoxItem.cs:
using System.Windows.Controls;
using System.Diagnostics;
namespace BindingPropagationTest.ComboBoxItems
{
public class PersonComboBoxItem : ComboBoxItem
{
private string _name = "";
public string name
{
get
{
return _name;
}
set
{
_name = value;
Content = _name;
}
}
public int age { get; set; }
public string address { get; set; }
public override string ToString()
{
Debug.WriteLine("name: " + name);
return name;
}
}
}
Running this application gives you this window:

And selecting a combobox item gives you this:

and as you can see, the name will not be filled in.
Why not?
You are almost there, a few things you need to change
Dependency properties are used like
There is a very strict convention that is necessary for dependency properties. It must be called “NameProperty” if the Property is called Name. Also the property just sets and gets the dependency property.
You can them Bind the textbox to the property in the usercontrol like
I added the x:Name=”UserControl” directive at the top, you could name it anything, as long as it matches the ElementName in the Binding
An extra note on how you are populating your comboBox
You could add a property on your MainWindow
then you can add to your main window the x:Name directive used on the usercontrol say
You can then use a datatemplate in your combobox as follows
Because ObservableCollection was used in the code-behind the combobox will automatically get items added or removed whenever the code-behind adds or removes items from the “ThePeople” collection. Just call
and the combobox will automatically populate with a new entry