Оценка производительности WPF Multibinding RelativeSource Findancestor

В случае следующего выражения MultiBinding, сколько раз механизм привязки будет искать предка DataGrid, если PropB изменяется несколько раз?

<MultiBinding Converter="{StaticResource TestConverter}"> 
    <Binding Path="PropA"/> 
    <Binding Path="PropB" /> 
    <Binding Path="DataContext.Sub.PropertyC" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType=DataGrid}" /> 
</MultiBinding>

Будет ли он искать только один раз, если PropertyC (и путь к нему) никогда не изменяется? Или он будет искать предка каждый раз, когда изменяется одно из свойств в мультисвязке? Предполагая, что есть уведомления об изменениях для каждого свойства.

1 ответ

Решение

Единственный способ проверить это можно, фактически удалив элементы управления, чтобы увидеть, находит ли он соответствующий элемент управления.

Тестируя его таким образом, он выглядит так, как будто он оценивается только один раз, с использованием MultiBinding или нет.

<Window x:Class="RelativeTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel x:Name="Stack">
        <TextBlock x:Name="TB1" Text="Foo" />
        <TextBlock x:Name="TB2" Text="Bar" />

        <Border BorderThickness="1" BorderBrush="Black" />

        <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel}, Path=Children[0].Text}" 
                   Foreground="Red" />

        <TextBlock Foreground="Blue">
            <TextBlock.Text>
                <MultiBinding StringFormat="{}{2}">
                    <Binding ElementName="TB1" Path="Text" />
                    <Binding ElementName="TB2" Path="Text" />
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=StackPanel}" Path="Children[0].Text" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
        <Button Click="ButtonBase_OnClick" Content="Remove 1st Child" />
    </StackPanel>
</Window>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        Stack.Children.Remove(Stack.Children[0]);
        TB1.Text = "You'll see me if I am looked up once.";
        TB2.Text = "You'll see me twice if I am re-evaulated each time";
    }
}

При запуске изначально вы увидите:

введите описание изображения здесь

При нажатии на кнопку, он удалит первый дочерний элемент и изменит текстовые блоки для отображения более нового текста, чтобы указать, к какому из них он теперь привязан.

введите описание изображения здесь

Другие вопросы по тегам