c# - BindingExpressionBase 在自定义 MarkupExtension 中为 null

标签 c# wpf binding markup-extensions

我有一个 CustomMarkupExtension 类。绑定(bind)正在工作 (!= null),但 BindingExpressionBase 始终为 null

有人可以解释一下为什么吗?我需要获取 BindingExpressionBase 来调用 UpdateTarget() 方法。

C# 代码

public class CustomMarkupExtension : MarkupExtension
{

    public BindingBase Binding { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (Binding == null) return null;

        BindingExpressionBase expression = Binding.ProvideValue(serviceProvider) as BindingExpressionBase;
        if (expression != null)
        {
            expression.UpdateTarget();
        }
        return expression;
    }
}

XAML 代码

<DataGrid ItemsSource="{Binding Path=Alarms, RelativeSource={RelativeSource TemplatedParent}}">
<DataGrid.Columns>
    <DataGridTemplateColumn>
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock Text="{Extensions:CustomMarkupExtension Binding={Binding Number}}"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

最佳答案

原因是您在模板内使用标记扩展(在本例中为 DataTemplate)。当您的标记扩展由 xaml 解析器解析时 - 尚未创建控件并且没有绑定(bind)目标。在这种情况下,您应该返回标记扩展本身(返回此)。如果您这样做 - 每次使用该模板创建控件时都会再次应用它。

内置 Binding 当然也遵循这种模式,这就是为什么它在目标时返回自身 (Binding) 而不是 BindingExpression对象尚不可用。因此,要解决此问题,您必须执行以下操作:

public class CustomMarkupExtension : MarkupExtension
{

    public BindingBase Binding { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider) {
        if (Binding == null) return null;

        var result = Binding.ProvideValue(serviceProvider);
        var expression = result as BindingExpressionBase;
        if (expression != null) {
            expression.UpdateTarget();
            return expression;
        }
        // no expression - return self to apply it again later
        return this;            
    }
}

如果您要创建不依赖其他扩展的自定义标记扩展(例如本例中的 Binding),您可以通过执行以下操作来检查您是否有目标:

var target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
bool hasTarget = target.TargetObject is DependencyObject;

关于c# - BindingExpressionBase 在自定义 MarkupExtension 中为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44106154/

相关文章:

c# - 如何将 JNI C# 类传递给 Java 或处理这种情况?

c# - 代码隐藏中的翻转 View 动画

c# - MVVM WPF在dataGrid中实现Find和FindNext

JavaFX 计算 Tableview 中不同字符串的出现而不进行迭代?

c# - MVVM 绑定(bind)到数组索引

c# - Microsoft.Reporting.WinForms 报告查看器控件错误尝试以其访问权限禁止的方式访问套接字

c# - 或整数

c# - 如何在 C# ASP.NET Core 中从没有 id 的 MySql 中选择一个项目

wpf - 如何提高 Canvas 渲染性能?

javascript - jquery,绑定(bind)订单/等待回调