views:

224

answers:

1

I have a scenario where I have a globally available Properties window (similar to the Properties window in Visual Studio), which is bound to a SelectedObject property of my model. I have a number of different ways to browse and select objects, so my first attempt was to bind them to SelectedObject directly. For example:

<ListBox ItemsSource="{Binding ActiveProject.Controllers}" 
SelectedItem="{Binding SelectedObject, Mode=TwoWay}"/>

<ListBox ItemsSource="{Binding ActiveProject.Machines}" 
SelectedItem="{Binding SelectedObject, Mode=TwoWay}"/>

This works well when I have more than one item in each list, but it fails if a list has only one item. When I select the item, SelectedObject is not updated, since the list still thinks its original item was selected. I believe this happens because the two way binding simply ignores the update from source when SelectedObject is not an object in the list, leaving the list's SelectedItem unchanged. In this way, the bindings become out of sync.

Does anybody know of a way to make sure the list boxes reset their SelectedItem when the SelectedObject is not in the list? Is there a better way to do this that doesn't suffer from this problem?

A: 

Well, I found a way around the issue, but it makes me slightly ill. I modified the SelectedObject property in my model to this:

public Object SelectedObject
{
    get
    {
        return _selectedObject;
    }
    set
    {
        if (value != _selectedObject)
        {
            //HACK
            //Pulse 'null' between changes to reset listening list controls
            if (value != null)
                SelectedObject = null;

            if (_selectedObject != null)
                SelectedObjects.Remove(_selectedObject);

            _selectedObject = value;
            if (value != null)
                SelectedObjects.Add(value);
        }
    }
}

This forces all of the data bound list controls to reset their SelectedItem to null before we update to the 'real' SelectedObject. On a side note, the NotifyPropertyChanged stuff is being handled by PostSharp, in case you were wondering why it's missing.

I'd prefer a less hackish solution, if possible, but I do like the fact that this keeps the bindings clean in the XAML (no change required.)

Dan Bryant