XAML 在 Silverlight 中动态评估绑定路径

Evaluate Binding Path Dynamically in Silverlight in XAML

如何动态评估绑定路径,即实际路径来自属性?例如,假设我有一个 属性 的 DisplayMemberPath,并且我想要这样的东西:

Content="{Binding Path=(DisplayMemberPath)}"

我知道这样不行,只是为了说明我的意思。 我知道如何通过代码构建自定义 DataTemplate 并动态设置它,但这不是我想要的。

您可以使用自定义行为:

<SomeControl>
    <Interaction.Behaviors>
        <DynamicBindingBehavior TargetProperty="Content"
            BindingPath="{Binding DisplayMemberPath}"/>
    </Interaction.Behaviors>
    ...
</SomeControl>

和代码:

public class DynamicBindingBehavior : Behavior<DependencyObject>
{
    private string m_targetProperty;
    public string TargetProperty
    {
        get { return m_targetProperty; }
        set
        {
            m_targetProperty = value;
            TryFindTargetProperty();
        }
    }

    private DependencyProperty m_targetDependencyProperty;

    private void TryFindTargetProperty()
    {
        if (m_targetProperty == null || AssociatedObject == null)
        {
            m_targetDependencyProperty = null;
        }
        else
        {
            var targetDependencyPropertyInfo = AssociatedObject.GetType()
                .GetProperty( TargetProperty + "Property", typeof( DependencyProperty ) );
            m_targetDependencyProperty =
                (DependencyProperty) targetDependencyPropertyInfo.GetValue(
                AssociatedObject, null );
        }
    }

    public string BindingPath
    {
        get { return (string) GetValue( BindingPathProperty ); }
        set { SetValue( BindingPathProperty, value ); }
    }

    public static readonly DependencyProperty BindingPathProperty =
        DependencyProperty.Register( "BindingPath", typeof( string ),
        typeof( DynamicBindingBehavior ),
        new PropertyMetadata( BindingPathChanged ) );

    private static void BindingPathChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        ((DynamicBindingBehavior) d).BindingPathChanged();
    }

    private void BindingPathChanged()
    {
        if (m_targetDependencyProperty == null) return;

        if (BindingPath == null)
        {
            AssociatedObject.ClearValue(m_targetDependencyProperty);
        }
        else
        {
            BindingOperations.SetBinding( AssociatedObject,
                m_targetDependencyProperty, new Binding( BindingPath ) );
        }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        TryFindTargetProperty();
    }

    protected override void OnDetaching()
    {
        if (m_targetDependencyProperty != null)
            AssociatedObject.ClearValue( m_targetDependencyProperty );

        base.OnDetaching();
        m_targetDependencyProperty = null;
    }
}