我怎样才能实现类似下面的东西
<CheckBox Content="{Binding Caption}">
<CheckBox.IsChecked>
<Binding Path="{Binding PropertyName}"
Source="{Binding Source}" />
</CheckBox.IsChecked>
</CheckBox>
在哪里
public class ViewModel
{
public string Caption { get; } = "Test";
public string PropertyName { get; } = nameof(Test.Property);
public object Source { get; } = new Test();
}
public class Test
{
public bool Property { get; set; } = false;
}
想法是供应Path
和 Source
(在设计时未知)通过属性进行绑定(bind)。
当前在 <Binding Path=
抛出异常行
A 'Binding' cannot be set on the 'Path' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
我会选择行为。以下行为将获取 Source 和 Path,并相应地更新 IsChecked 属性的绑定(bind)。您可以扩展它以满足您的需要。目前这仅限于 IsChecked 属性,您可以编写通用代码来支持所有属性。
public class CheckBoxCustomBindingBehavior : Behavior<CheckBox>
{
protected override void OnAttached()
{
base.OnAttached();
}
public object Source
{
get
{
return (object)GetValue(SourceProperty);
}
set
{
SetValue(SourceProperty, value);
}
}
// Using a DependencyProperty as the backing store for Source. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(object), typeof(CheckBoxCustomBindingBehavior), new PropertyMetadata(null, OnSourceChanged));
private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as CheckBoxCustomBindingBehavior).ModifyBinding();
}
public string Path
{
get
{
return (string)GetValue(PathProperty);
}
set
{
SetValue(PathProperty, value);
}
}
// Using a DependencyProperty as the backing store for Path. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PathProperty =
DependencyProperty.Register("Path", typeof(string), typeof(CheckBoxCustomBindingBehavior), new PropertyMetadata(string.Empty, OnPathChanged));
private static void OnPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as CheckBoxCustomBindingBehavior).ModifyBinding();
}
private void ModifyBinding()
{
var source = Source ?? AssociatedObject.DataContext;
if (source != null && !string.IsNullOrEmpty(Path))
{
Binding b = new Binding(Path);
b.Source = source;
AssociatedObject.SetBinding(CheckBox.IsCheckedProperty, b);
}
}
}
和 Xaml 用法,
<CheckBox xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">
<i:Interaction.Behaviors>
<local:CheckBoxCustomBindingBehavior Path="{Binding SelectedPath}" Source="{Binding}" />
</i:Interaction.Behaviors>
</CheckBox>
SelectedPath 来自模型,这就是我存储属性名称的地方。
注意:您将需要交互组件。