1
Vote

Binding does not work on SelectedObjects of PropertyGrid.

description

I'm working with the property 'SelectedObjects' of PropertyGrid.

My code is so simple, but binding does not work.

On Debug mode, I can see that SelectedObjects of propertygrid has some items chosen, but I cannot see the properties on the control.

Is there anything I missed?

The code is...

-- .xaml --
<Grid>
        <p:PropertyGrid
            x:Name="PropertyGrid"
            SelectedObjects="{Binding SelectedModels}"
            CategoryControlType="Expander" 
            EnumAsRadioButtonsLimit="1" />
</Grid>
-- .cs --
SelectedModels = new ObservableCollection<object>();

...

/// <summary>
/// Gets selected models.
/// </summary>
public ObservableCollection<object> SelectedModels { get; private set; }

comments

objo wrote Aug 15, 2014 at 12:36 PM

I think this should be posted under discussion, if it is not a bug or a feature request.

You also need to show what kind of objects you are adding to the collection, this is probably where the problem is.

labstyrotentasto wrote Aug 17, 2014 at 5:36 AM

I added some codes in 'PropertyGrid.cs' as follows.
/// <summary>
/// Handles changes in SelectedObjects.
/// </summary>
/// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs" /> instance containing the event data.</param>
private void SelectedObjectsChanged(DependencyPropertyChangedEventArgs e)
{
    if (e.OldValue != null)
    {
        INotifyCollectionChanged collection = e.OldValue as INotifyCollectionChanged;
        if (collection != null)
            collection.CollectionChanged -= new NotifyCollectionChangedEventHandler(SelectedObjects_CollectionChanged);

        NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, e.OldValue as IList);
        SelectedObjects_CollectionChanged(e.NewValue, args);
    }

    if (e.NewValue != null)
    {
        INotifyCollectionChanged collection = e.NewValue as INotifyCollectionChanged;
        if (collection != null)
            collection.CollectionChanged += new NotifyCollectionChangedEventHandler(SelectedObjects_CollectionChanged);

        NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, e.NewValue as IList);
        SelectedObjects_CollectionChanged(e.NewValue, args);
    }
    else
        this.CurrentObject = null; 
}

List<object> selectedObjects = new List<object>();
void SelectedObjects_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
            foreach (var item in e.NewItems)
            {
                if (!selectedObjects.Contains(item))
                    selectedObjects.Add(item);
            }
            break;

        case NotifyCollectionChangedAction.Remove:
            foreach (var item in e.OldItems)
            {
                if (selectedObjects.Contains(item))
                    selectedObjects.Remove(item);
            }
            break;

        case NotifyCollectionChangedAction.Reset:
            selectedObjects.Clear();
            break;

        default:
            break;
    }

    if (selectedObjects.Count == 0)
        this.CurrentObject = null;
    else if (selectedObjects.Count == 1)
        this.CurrentObject = selectedObjects[0];
    else
        this.CurrentObject = new ItemsBag(selectedObjects);

    this.UpdateControls();
}
I'm not sure that this is the best solution, but it works well in my case.