c# - Binding.Path绑定(bind)

标签 c# wpf mvvm binding

<分区>

我怎样才能实现类似下面的东西

<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;
}

想法是供应PathSource (在设计时未知)通过属性进行绑定(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 来自模型,这就是我存储属性名称的地方。

注意:您将需要交互组件。

关于c# - Binding.Path绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41482038/

相关文章:

C# UWP 使用 System.IO.Directory 返回空数组?

c# - 重写Linq 'to other format'

wpf - 多选 WPF 列表框通过单击进行多项选择

wpf - 带有单行 TabPanel 和溢出面板的 TabControl

.net - WPF:如何为组件列表添加动画?

javascript - 我是否总是使用 Knockout 映射插件来制作我的 View 模型,从而过度使用它?

c# - 这两种说法是同一回事吗?

c# - 这个 LINQ 表达式是如何工作的?

c# - 如何摆脱 WPF MVVM View 模型中的重复属性

c# - 在模块化 Prism WPF 应用程序中,我应该在哪里放置公共(public)字符串资源和公共(public) XAML ResourceDictionary?