WPF FindAncestor performance issues

402 views Asked by At

Using FindAncestor in Binding have a problem about Performance issues.

I want to use Base's DataContext in Child User Control or ListBoxItem/ListViewItem.

What is alternative about this problem?

FindAncestor

2

There are 2 answers

0
Mark Feldman On

Give the parent a name and bind to it with ElementName=.

0
Bruno V On

Instead of traversing up the Visual Tree with FindAncestor, you could traverse up the DataContext of your current control. To be able to do this, you need a reference in your ViewModels to the parent ViewModel. I usually have a base ViewModel class that has a property Parent and Root:

public abstract class ViewModel : INotifyPropertyChanged
{
    private ViewModel parentViewModel;

    public ViewModel(ViewModel parent)
    {
        parentViewModel = parent;
    }

    /// <summary>
    /// Get the top ViewModel for binding (eg Root.IsEnabled)
    /// </summary>
    public ViewModel Root
    {
        get
        {
            if (parentViewModel != null)
            {
                return parentViewModel.Root;
            }
            else
            {
                return this;
            }
        }
    }
}

In the XAML, you can then replace this:

<ComboBox x:Name="Sector" 
                 ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.SectorList}" 
                 SelectedValuePath="Id" 
                 SelectedValue="{Binding SectorId, Mode=TwoWay}" />

By this:

<ComboBox x:Name="Sector" 
                 ItemsSource="{Binding Root.SectorList}" 
                 SelectedValuePath="Id" 
                 SelectedValue="{Binding SectorId, Mode=TwoWay}" />

One requirement: the Root properties always have to exist on the topmost ViewModel.