[Edit]: I figured out how to do this on my own. I posted my solution in the hope that it will save someone else a few days of Googling. If you are a WPF guru, please look at my solution and let me know if there is a better / more elegant / more efficient way to do this. In particular, I am interested in knowing what I don't know... how is this solution going to screw me down the road? The problem really boils down to exposing inner control properties.
Problem: I am creating some code to auto-generate a data-bound GUI in WPF for an XML file. I have an xsd file that can help me determine the node types, etc. Simple Key/Value elements are easy.
When I parse this element:
<Key>value</Key>
I can create a new 'KeyValueControl' and set the DataContext
to this element. The KeyValueControl
is defined as a UserControl
and just has some simple bindings on it. It works great for any simple XElement.
The XAML inside this control looks like this:
<Label Content={Binding Path=Name} />
<TextBox Text={Binding Path=Value} />
The result is a line that has a label with the element name and a text box with the value that I can edit.
Now, there are times where I need to display lookup values instead of the actual value. I would like to create a 'KeyValueComboBox' similar to the above KeyValueControl
but be able to specify (based on information in the file) the ItemsSource
, DisplayMemberPath
, and ValueMemberPath
. The 'DisplayMemberPath' and 'ValueMemberPath' bindings would be the same as the KeyValueControl
.
I don't know if a standard user control can handle this, or if I need to inherit from Selector
.
The XAML in the control would look something like this:
<Label Content={Binding Path=Name} />
<ComboBox SelectedValue={Binding Path=Value}
ItemsSource={Binding [BOUND TO THE ItemsSource PROPERTY OF THIS CUSTOM CONTROL]
DisplayMemberPath={Binding [BOUND TO THE DisplayMemberPath OF THIS CUSTOM CONTROL]
SelectedValuePath={Binding [BOUND TO THE SelectedValuePath OF THIS CUSTOM CONTROL]/>
In my code, I would then do something like this (assuming that this node is a 'Thing' and needs to display a list of Things so the user can select the ID:
var myBoundComboBox = new KeyValueComboBox();
myBoundComboBox.ItemsSource = getThingsList();
myBoundComboBox.DisplayMemberPath = "ThingName";
myBoundComboBox.ValueMemberPath = "ThingID"
myBoundComboBox.DataContext = thisXElement;
...
myStackPanel.Children.Add(myBoundComboBox)
So my questions are:
1) Should I inherit my KeyValueComboBox
from Control
or Selector
?
2) If I should inherit from Control
, how do I expose the inner Combo Box's ItemsSource
, DisplayMemberPath
, and ValueMemberPath
for binding?
3) If I need to inherit from Selector, can someone provide a small example of how I might get started with that? Again, I'm new to WPF so a nice, simple example would really help if that's the road I need to take.