Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
585
ComboBox ItemsSource dependent on other property in XamPropertyGrid
posted

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

Parents
No Data
Reply
  • 5170
    Offline posted

    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)

                  {

                         if (e.PropertyItem.DisplayName != "Table")

                               return;

     

                         var parent = e.PropertyItem.GetParentItem();

     

                         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.

Children
No Data