Hi,
I have a XamPropertyGrid looking at an object structure similar to the one below. The top level selected object has a list of filters, which each have a table and field. These table and field properties are both comboboxes, and the items source of the Field is the fields property of the selected table object. The only solution I can find to create the ItemsSource binding on the Field combobox is to create a converter which uses reflection to get the internal ParentItem property from the PropertyGridItem and find the table from there. Doing it like this works, but obviously isn't how I'd want to do it and it means that the binding does not receive the property change notification when the table changes, so I have to collapse and expand the filter in the property grid to get the fields list to update.
Is there a better way to do this?
- Name- Filters |- 0 |- Table |- Field |- Value |- 1 |- Table |- Field |- Value
Many thanks,
Richard
The issue here is that in order for a ValueConverter to be invoked, the bound value must be modified. In this case, you are binding to the “Field” PropertyGridItem. So you have two options to achieve your goal. The first being that you use a MultiBining for the ItemSource of the ComboBox and provide not only the PropertyGridPropertyItem as a binding value, but also another property such as the description.
<ComboBox x:Name="_cboFields"
SelectedItem="{Binding Value, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource TableFieldsConverter2}">
<Binding Path="." />
<Binding Path="Description" />
</MultiBinding>
</ComboBox.ItemsSource>
</ComboBox>
Then use an IMultiValueConverter:
public class TableFieldsConverter2 : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
var value = values[0];
var item = value as PropertyGridItem;
if (item != null)
var table = (item.GetParentObject() as SubThing)?.Table;
return table?.Fields;
}
return null;
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
throw new NotImplementedException();
And then modify the description property of the “Field” PropertyGridItem in the PropertyGrid.PropertyItemValueChanging/Changed event to get the binding to update which would then invoke the value converter again:
private void XamPropertyGrid_PropertyItemValueChanged(object sender, PropertyItemEventArgs e)
if (e.PropertyItem.DisplayName != "Table")
return;
var parent = e.PropertyItem.GetParentItem();
foreach (var item in parent.Children)
if (item.DisplayName == "Field")
var descr = item.Description;
item.Description = "Temp";
item.Description = descr;
Option Two would be to keep everything like you have it and just automatically expand and collapse the SubThing PropertyGridPropertyItem in code in the PropertyGrid.PropertyItemValueChanging/Changed event.
private void XamPropertyGrid_PropertyItemValueChanging(object sender, PropertyItemEventArgs e)
parent.IsExpanded = false;
parent.IsExpanded = true;
We will look at adding an attribute that would allow you to re-evaluate a property based on the event in which another property value changes. Until then, you can use one of these workarounds to get you unblocked.