WPF derived ComboBox SelectedValuePath issue
In our application we have a very large set of data that acts as our data dictionary for ComboBox 开发者_高级运维lists, etc. This data is staticly cached and keyed off of 2 variables, so I thought it wise to write a control that derived from ComboBox and exposed the 2 keys as DPs. When those 2 keys have proper values I set the ItemsSource of the ComboBox automatically from the data dictionary list it corresponds to. I also automatically set the SelectedValuePath and DisplayMemberPath in the constructor to Code and Description, respectively.
Here's how an example of how an item in the ItemsSource from the data dictionary list always looks:
public class DataDictionaryItem
{
public string Code { get; set; }
public string Description { get; set; }
public string Code3 { get { return this.Code.Substring(0, 3); } }
}
The value of Code is always 4 characters long, but sometimes I only need to bind 3 characters of it. Hence, the Code3 property.
Here's how the code looks inside my custom combobox to set the ItemsSource:
private static void SetItemsSource(CustomComboBox combo)
{
if (string.IsNullOrEmpty(combo.Key1) || string.IsNullOrEmpty(combo.Key2))
{
combo.ItemsSource = null;
return;
}
List<DataDictionaryItem> list = GetDataDictionaryList(combo.Key1, combo.Key2);
combo.ItemsSource = list;
}
Now, my problem is, when I change the SelectedValuePath in the XAML to Code3, it doesn't work. What I bind to SelectedValue still gets the full 4 character Code from DataDictionaryItem. I even tried rerunning SetItemsSource when the SelectedValuePath was changed and no dice.
Can anyone see what I need to do to get my custom combobox to wake up and use the SelectedValuePath provided if it's overridden in the XAML? Tweaking the value in the property setter in my SelectedValue bound business object is not an option.
Here's how the XAML looks for my combobox in a form:
<c:CustomComboBox Key1="0" Key2="8099" SelectedValuePath="Code3" SelectedValue="{Binding Thing}"/>
EDIT: I just ran snoop on my code and it says my SelectedValuePath is Code... it doesn't appear to ever be set to Code3... Zuh?
Ok, I figured it out.
Apparently setting the default values of a DependencyProperty in the default non-static constructor of a WPF control is a no-no. So, at first I tried this:
static ValueCodeListComboBox()
{
SelectedValuePathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new PropertyMetadata("Code"));
DisplayMemberPathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new PropertyMetadata("Description"));
}
But this kept throwing an error saying:
Metadata override and base metadata must be of the same type or derived type.
Finally figured out that meant I needed to use FrameworkPropertyMetadata instead of PropertyMetadata:
static ValueCodeListComboBox()
{
SelectedValuePathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new FrameworkPropertyMetadata("Code"));
DisplayMemberPathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new FrameworkPropertyMetadata("Description"));
}
Now changing SelectedValuePath in the XAML works great.
精彩评论