Click here to Skip to main content
15,879,348 members
Articles / Programming Languages / C#

Binding to ComboBox.SelectedItem through a custom dependency property

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
21 Oct 2009CPOL2 min read 44.6K   9   9
Today we are looking into databinding to the ComboBox.SelectedItem property through a custom dependency property in a UserControl.

Today we are looking into databinding to the ComboBox.SelectedItem property through a custom dependency property in a UserControl.

Post 42

But before all that I want to let you all know, this is post #42 on Developers 42. For obvious reasons, this is a special post on my blog. As I started out last year, I didn't have any visitors, but now I average about 1700 visits a month. A large part of these visits come through Google, but a special thanks goes out to Dave Campbell for publishing a lot of my articles on SilverlightCream.com. Through his great efforts of bringing us the latest and greatest on Silverlight, his website is the second greatest referrer, only topped by Google. I won't elaborate any more on this. Stats, highs and lows will all be published in October when the blog celebrates it's first year of existence.

Binding to ComboBox.SelectedItem through a custom dependency property in a UserControl, I ran into this building a user control based on the requirement that we need a combo box that includes an edit button next to it when needed and also provides a label when needed. The simplest way to do this (at least as I see it), is through building two UserControls. The first combines the ComboBox with a Button and the second combines the result with a TextBlock. Today we want to focus on the first one, which I dubbed ExtendedComboBox. I wrote the following XAML as a start:

XML
<UserControl
xmlns:input="clr-namespace:System.Windows.Controls;
	assembly=System.Windows.Controls.Input"
xmlns:inputToolkit="clr-namespace:System.Windows.Controls;
	assembly=System.Windows.Controls.Input.Toolkit"
x:Class="ExtendedComboBox.ExtendedComboBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
x:Name="extendedComboBoxControl"
>
<StackPanel x:Name="stackPanel" Orientation="Horizontal" HorizontalAlignment="Stretch">
<ComboBox x:Name="comboBox"
HorizontalAlignment="Stretch"
SelectionChanged="comboBox_SelectionChanged"
>
</ComboBox>
<Button x:Name="editButton" Content="..." Padding="5,0,5,0"
    LayoutUpdated="editButton_LayoutUpdated"
Click="editButton_Click"/>
</StackPanel>
</UserControl>

Simple enough. All I had to do now was add some dependency properties to control some functionality and Bob's your uncle, right? Wrong! I will spare you the details on sizing specifics and events, as this is not the focus of this article.

For databinding, I figured I would need to bind to the ItemsSource and the SelectedItem properties of the ComboBox. Here is the code I initially came up with:

C#
publicIEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set
{
SetValue(ItemsSourceProperty, value);
comboBox.ItemsSource = value;
}
}

// Using a DependencyProperty as the backing store for ItemsSource.
// This enables animation, styling, binding, etc...
publicstaticreadonlyDependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable),
    typeof(ExtendedComboBox), newPropertyMetadata(null));

publicobject SelectedItem
{
get { return (object)GetValue(SelectedItemProperty); }
set
{
SetValue(SelectedItemProperty, value);
comboBox.SelectedItem = SelectedItem;
}
}

// Using a DependencyProperty as the backing store for SelectedItem.
// This enables animation, styling, binding, etc...
publicstaticreadonlyDependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(ExtendedComboBox),
    newPropertyMetadata(null));

As you can see, these are standard dependency properties, only I've added a line to assign their values through to the ComboBox. For the ItemsSource property this works like a charm, however, for the SelectedItem property it doesn't.

After struggling with this, building a complete test rig and reading through books worth of blog posts, I finally came up with the following solution. I removed the passing through of the value in the properties setter method and added manual binding for the property in the constructor of the ExtendedCombobox. Here is my new constructor:

C#
public ExtendedComboBox()
{
InitializeComponent();
Binding selectedItemBinding = newBinding("SelectedItem");
selectedItemBinding.Source = this;
selectedItemBinding.Mode = BindingMode.TwoWay;
comboBox.SetBinding(ComboBox.SelectedItemProperty, selectedItemBinding);
}

This way the ExtendedComboBox becomes the source of the binding for the ComboBox.SelectedItem property. After adding this (and obviously also implementing the Equals and GetHashCode methods on the business objects involved), it now works like a charm, without having to write any extra code in the modules that use this control.

Please leave me a comment if you have any questions, remarks or if you just want to say hi.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) KnowledgePlaza
Netherlands Netherlands
Since early 2001 I've been working full time as a software developer and since 2004 I've been working mostly with Microsoft technology.
I started out as a product developer, but after a few years I switched to a project company where my roles ranged from developer up to consultant and from team lead and coach to manager.
Eventually I switched jobs and focused on the consultant part and then I got back to building a product once again. Now I work in a job where I get to do both.

Comments and Discussions

 
QuestionHaving the same problem but no solution Pin
Member 1307594321-Mar-17 23:03
Member 1307594321-Mar-17 23:03 
AnswerRe: Having the same problem but no solution Pin
mrjvdveen23-Mar-17 0:20
professionalmrjvdveen23-Mar-17 0:20 
GeneralRe: Having the same problem but no solution Pin
Member 1307594324-Mar-17 4:31
Member 1307594324-Mar-17 4:31 
GeneralRe: Having the same problem but no solution Pin
Member 1307594330-Mar-17 4:57
Member 1307594330-Mar-17 4:57 
QuestionWhy do you have to create duplicate DPs Pin
PeteBarber4-Jul-11 12:23
PeteBarber4-Jul-11 12:23 
AnswerRe: Why do you have to create duplicate DPs Pin
mrjvdveen11-Aug-11 20:29
professionalmrjvdveen11-Aug-11 20:29 
GeneralProblem with Binding SelectedValue and SelectedItem for a combo through a usercontrol Pin
ety.5-Oct-10 0:17
ety.5-Oct-10 0:17 
GeneralRe: Problem with Binding SelectedValue and SelectedItem for a combo through a usercontrol Pin
mrjvdveen22-Dec-10 21:01
professionalmrjvdveen22-Dec-10 21:01 
That's odd. It realy should work the same unless you have some other code in your constructor too. Loaded is called right after the constructor. The only difference is it can be unloaded at some point. Anyway, the loaded event is better, so thanks. Thumbs Up | :thumbsup:
GeneralRe: Problem with Binding SelectedValue and SelectedItem for a combo through a usercontrol Pin
Daniel Balogh12-Aug-16 8:06
Daniel Balogh12-Aug-16 8:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.