Jef Patat
Jef Patat

Reputation: 999

Change binding when focus changes

I have an application that has several treeviews and one propertygrid (from the extended WPF toolkit). The goal is to display the properties of the selected item. I'm fairly new to WPF so I started with one treeview and bind the propertygrids selected object like this

<xctk:PropertyGrid x:Name="xctkPropertyGrid"
                       Grid.Column="2"
                       ShowSearchBox="False"
                       ShowSortOptions="False"
                       SelectedObject="{Binding ElementName=actionsTreeView, Path=SelectedItem, Mode=OneWay}">
</xctk:PropertyGrid>

This seems to work fine. But it off course binds to actionsTreeView all the time. What I would really need is an update of that propertygrid when the focus changes to another selecteditem in another treeview. I have achieved my goal using the SelectedItemChanged of each treeview and set the propertygrids selectedobject like so. Is this somehow possible using databinding and triggers. My solution adds some code behind and tight coupling and that doesn't feel very MVVM.

kind regards, Jef

Upvotes: 4

Views: 309

Answers (1)

Jef Patat
Jef Patat

Reputation: 999

Ok, here's how I ended up solving my problem:

Each treeview is bound to a viemodel property on the main viewmodel. I also created a SelectedItem property on the main viewmodel like this to which the propertygrid's SelectedObject is bound:

private object selectedItem;
public object SelectedItem
{
    get { return selectedItem; }
    set
    {
        selectedItem = value;
        OnPropertyChanged("SelectedItem");
    }
}

I then attach a behavior to each treeview that updates this SelectedItem:

public class UpdateSelectedItemBehavior : Behavior<TreeView>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        this.AssociatedObject.GotFocus += AssociatedObject_GotFocus;
        this.AssociatedObject.SelectedItemChanged += AssociatedObject_SelectedItemChanged;
    }

    void AssociatedObject_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        ViewModels.MainViewModel mainViewModel = AssociatedObject.DataContext as ViewModels.MainViewModel;
        if (mainViewModel != null)
        {
            mainViewModel.SelectedItem = AssociatedObject.SelectedItem;
        }
    }

    void AssociatedObject_GotFocus(object sender, RoutedEventArgs e)
    {
        ViewModels.MainViewModel mainViewModel = AssociatedObject.DataContext as ViewModels.MainViewModel;
        if (mainViewModel != null)
        {
            mainViewModel.SelectedItem = AssociatedObject.SelectedItem;
        }
    }
}

Upvotes: 1

Related Questions