首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Binding.Path结合

Binding.Path结合
EN

Stack Overflow用户
提问于 2017-01-05 10:02:49
回答 3查看 1.9K关注 0票数 3

我怎样才能实现以下的目标

代码语言:javascript
运行
复制
<CheckBox Content="{Binding Caption}">
    <CheckBox.IsChecked>
        <Binding Path="{Binding PropertyName}"
                 Source="{Binding Source}" />
    </CheckBox.IsChecked>
</CheckBox>

哪里

代码语言:javascript
运行
复制
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 (设计时未知)。

当前,此抛出异常位于<Binding Path=行。

不能在“绑定”类型的“路径”属性上设置“绑定”。“绑定”只能设置在DependencyProperty的DependencyObject上。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-01-05 11:02:23

我要做的就是行为。下面的行为将获得源和路径,并相应地更新IsChecked属性的绑定。你可以扩展这个以满足你的需要。现在,这仅限于IsChecked属性,您可以编写支持所有属性的泛型代码。

代码语言:javascript
运行
复制
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的使用,

代码语言:javascript
运行
复制
 <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来自于模型,而这就是我存储属性名称的地方。

注意:您将需要交互式程序集。

票数 4
EN

Stack Overflow用户

发布于 2017-01-05 11:13:36

必须在编译时知道源属性的名称,才能在XAML中设置绑定:

代码语言:javascript
运行
复制
<CheckBox Content="{Binding Caption}">
    <CheckBox.IsChecked>
        <Binding Path="Source.Property" />
    </CheckBox.IsChecked>
</CheckBox>

正如错误消息告诉您的,不能将某些内容绑定到绑定的Path属性。

如果在设计时不知道要绑定到的属性的名称,可以通过编程方式设置绑定:

代码语言:javascript
运行
复制
<CheckBox x:Name="ck" Content="{Binding Caption}" />
代码语言:javascript
运行
复制
ViewModel vm = new ViewModel();
ck.DataContext = vm;
ck.SetBinding(CheckBox.IsCheckedProperty, new Binding(vm.PropertyName) { Source = vm.Source });

但是,在纯XAML中无法做到这一点。记住,XAML是一种标记语言。

票数 3
EN

Stack Overflow用户

发布于 2017-01-05 14:45:48

在看到@WPFUser one之后,回答有点晚,但它支持任何属性,我个人不喜欢混合依赖关系:

代码语言:javascript
运行
复制
public class DynamicBinding
{
    public static object GetSource(DependencyObject obj) => (object)obj.GetValue(SourceProperty);
    public static void SetSource(DependencyObject obj, object value) => obj.SetValue(SourceProperty, value);
    public static readonly DependencyProperty SourceProperty =
        DependencyProperty.RegisterAttached("Source", typeof(object), typeof(DynamicBinding), new PropertyMetadata(null, (d, e) => SetBinding(d)));

    public static string GetProperty(DependencyObject obj) => (string)obj.GetValue(PropertyProperty);
    public static void SetProperty(DependencyObject obj, string value) => obj.SetValue(PropertyProperty, value);
    public static readonly DependencyProperty PropertyProperty =
        DependencyProperty.RegisterAttached("Property", typeof(string), typeof(DynamicBinding), new PropertyMetadata(null, (d, e) => SetBinding(d)));

    public static string GetTarget(DependencyObject obj) => (string)obj.GetValue(TargetProperty);
    public static void SetTarget(DependencyObject obj, string value) => obj.SetValue(TargetProperty, value);
    public static readonly DependencyProperty TargetProperty =
        DependencyProperty.RegisterAttached("Target", typeof(string), typeof(DynamicBinding), new PropertyMetadata(null, (d, e) => SetBinding(d)));

    static void SetBinding(DependencyObject obj)
    {
        var source = GetSource(obj);
        var property = GetProperty(obj);
        var target = GetTarget(obj);
        // only if all required attached properties values are set
        if (source == null || property == null || target == null)
            return;
        BindingOperations.SetBinding(obj, DependencyPropertyDescriptor.FromName(target, obj.GetType(), obj.GetType()).DependencyProperty,
            new Binding(property) { Source = source });
    }
}

用途如下:

代码语言:javascript
运行
复制
<CheckBox Content="{Binding Caption}"
          local:DynamicBinding.Property="{Binding PropertyName}"
          local:DynamicBinding.Source="{Binding Source}"
          local:DynamicBinding.Target="IsChecked" />

Target可以是控件的任何依赖项属性。它是一个普通的字符串,不知道如何改进它,以获得intellisense的帮助时,进入它。

ToDo:如果更改了Target (它将反映对SourceProperty所做的更改),则不会删除绑定,不支持多个动态绑定(例如,对控件的不同属性)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41482038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档