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;
}
}
如何动态评估绑定路径,即实际路径来自属性?例如,假设我有一个 属性 的 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;
}
}