You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#标记中直接绑定View到另一个View(无XAML/ViewModel)

纯C#代码实现View间直接绑定的解决方案

问题描述

完全通过C#代码创建视图(不使用XAML),已有DataTemplate,能轻松将视图绑定到ViewModel,但希望实现View之间的直接绑定(如Label绑定Border的IsFocused属性),仅找到XAML实现示例,自行编写的代码无法运行,推测Label的Binding未正确指定Border作为绑定源。

错误代码示例

internal class BinaryItemDataTemplate : DataTemplate
{
    internal BinaryItemDataTemplate()
    {
        LoadTemplate = static () =>
        {
            Label label = new() { Text = "unset" };
            var border = new Border();
            label.SetBinding(Label.TextProperty, nameof(border.IsFocused)); // 未指定绑定源

            return border;
        };
    }
}

现有间接绑定方案(通过ViewModel)

目前可通过ViewModel中转实现绑定,但希望省去中间层:

// Border绑定ViewModel的IsFocused属性
border.SetBinding(Border.IsFocusedProperty, nameof(BinaryItem.IsFocused), BindingMode.TwoWay);
// Label绑定ViewModel的IsFocused属性
selectedLabel.SetBinding(Label.TextProperty, nameof(BinaryItem.IsFocused));

直接绑定的正确实现

要实现View间直接绑定,需解决两个核心问题:

  1. 将Label添加到Border的可视化树中(否则Label不会显示);
  2. 为Binding显式指定Border作为绑定源(默认绑定源是控件的DataContext,而非同级/父级View控件)。

方案1:直接指定Binding.Source

internal class BinaryItemDataTemplate : DataTemplate
{
    internal BinaryItemDataTemplate()
    {
        LoadTemplate = static () =>
        {
            Label label = new() { Text = "unset" };
            var border = new Border();
            // 将Label设置为Border的子控件
            border.Child = label;

            // 创建绑定并指定源为当前Border
            var binding = new Binding(nameof(Border.IsFocused))
            {
                Source = border,
                // 可选:添加布尔转字符串的转换器,让显示更友好
                Converter = new BooleanToStringConverter()
            };
            label.SetBinding(Label.TextProperty, binding);

            return border;
        };
    }
}

方案2:使用ElementName(需为Border命名)

internal class BinaryItemDataTemplate : DataTemplate
{
    internal BinaryItemDataTemplate()
    {
        LoadTemplate = static () =>
        {
            Label label = new() { Text = "unset" };
            var border = new Border { Name = "TargetBorder" };
            border.Child = label;

            var binding = new Binding(nameof(Border.IsFocused))
            {
                ElementName = "TargetBorder",
                Converter = new BooleanToStringConverter()
            };
            label.SetBinding(Label.TextProperty, binding);

            return border;
        };
    }
}

补充:布尔转字符串转换器

由于IsFocused是布尔类型,而Label.Text是字符串类型,需要实现一个转换器来完成类型转换:

public class BooleanToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool isFocused)
        {
            return isFocused ? "已聚焦" : "未聚焦";
        }
        return "unset";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 单向绑定无需实现反向转换
        throw new NotImplementedException();
    }
}

内容的提问来源于stack exchange,提问作者axa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 20:41:23