2

我在 WPF 中遇到数据绑定问题。

当我尝试使用值转换器并将 NotifyOnTargetUpdated=True 属性设置为 True 时,我收到带有以下消息的 XamlParseException:

“System.Windows.Data.BindingExpression”值不能分配给对象“View.UserControls.ShadowedText”的属性“Contenu”。值不能为空。参数名称:标记文件“View.UserControls;component/saletotal.xaml”第 363 行位置 95 中对象“System.Windows.Data.Binding”处的 textToFormat 错误。

绑定非常标准:

<my:ShadowedText Contenu="{Binding Path=Total,
                                   Converter={StaticResource CurrencyToStringConverter},
                                   NotifyOnTargetUpdated=True}"
                 TargetUpdated="MontantTotal_TargetUpdated">
</my:ShadowedText>

(为简洁起见删除了样式属性)

转换器存在于资源中,并在 NotifyOnTargetUpdated=True 被移除时正常工作。同样,正确调用和实现 TargetUpdated 事件,并在删除转换器时工作。

注意:此绑定是在 ControlTemplate 中定义的,尽管我认为这与问题无关。

谁能解释我发生了什么?我定义绑定错误吗?这些功能是否相互排斥(在这种情况下,您能解释一下为什么会这样)吗?

提前致谢。

更多信息:这是 TargetUpdated 处理程序的内容:

private void MontantTotal_TargetUpdated(object sender, DataTransferEventArgs e)
{
    ShadowedText textBlock = (ShadowedText)e.TargetObject;
    double textSize = textBlock.Taille;
    double delta = 5;
    double defaultTaille = 56;
    double maxWidth = textBlock.MaxWidth;
    while (true)
    {
        FormattedText newFormat = new FormattedText(textBlock.Contenu,
                                                    CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                                                    new Typeface("Calibri"), textSize,
                                                    (SolidColorBrush) Resources["RougeVif"]);
        if (newFormat.Width < textBlock.MaxWidth && textSize <= defaultTaille)
        {
            if ((Math.Round(newFormat.Width) + delta) >= maxWidth || textSize == defaultTaille)
            {
                break;
            }
            textSize++;
        }
        else
        {
            if ((Math.Round(newFormat.Width) - delta) <= maxWidth && textSize <= defaultTaille)
            {
                break;
            }
            textSize--;
        }
    }

    textBlock.Taille = textSize;
}

处理程序的作用是根据内容的长度调整控件的大小。这很丑陋,但我想让功能部分在重构之前工作。

4

1 回答 1

2

如果您收到 XamlParseException,这意味着在此控件的初始化期间发生了此错误。

指定后,将在NotifyOnTargetUpdated=TrueInitializeComponent 调用中引发 TargetUpdated 事件。在这一点上,您是否拥有 DataContext 令人难以置信,因此绑定将评估为 null。通常,没有问题,但是您请求在更新属性时引发事件。

所以它用一个空textBlock.Contenu值来触发你的事件处理程序,你将它传递给 FormattedText 的第一个参数(名为textToFormat),它抛出了一个 ArgumentNullException。

在运行代码之前,练习一些防御性编程并检查textBlock.Contenunull 值。

两个提示供将来参考:

1)收到异常时,粘贴整个堆栈跟踪,包括InnerException(所以调用Exception.ToString)。通常,您会看到它发生在哪里。如果没有,这里的人会比你得到答案更快地看到它发生在哪里。

2) 当接收到异常时,如果你不知道它是从哪里抛出的(你显然不知道,或者你已经在代码中看到了它),强制 Visual Studio 中断所有异常。 http://msdn.microsoft.com/en-us/library/d14azbfh(VS.80).aspx

(请注意,根据您的设置,它们引用的菜单项可能存在也可能不存在。您也可以使用 CTRL+ALT+E 打开“例外”对话框。)

使用此设置,调试器将停止在引发异常的确切代码行上。

于 2010-06-16T13:34:13.260 回答