WPF Multibinding RelativeSource Findancestor评估性能

时间:2017-08-28 21:09:34

标签: c# wpf multibinding findancestor

在以下MultiBinding表达式的情况下,如果PropB多次更改,绑定引擎会搜索DataGrid祖先多少次?

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

如果PropertyC(及其路径)永远不会改变,它只会搜索一次吗?或者,每当多重绑定中的一个属性发生变化时,它会搜索祖先吗?假设每个属性都有变更通知。

1 个答案:

答案 0 :(得分:2)

我认为可以测试的唯一方法是实际删除控件以查看它是否找到了正确的控件。

以这种方式进行测试,看起来好像只评估一次是否使用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";
    }
}

最初运行时,您会看到:

enter image description here

单击该按钮时,它将删除第一个子项并更改TextBlocks以显示更新的文本以指示它现在绑定到哪个。

enter image description here