【问题标题】:WPF Converter and NotifyOnTargetUpdated exclusive in a binding?WPF Converter 和 NotifyOnTargetUpdated 在绑定中独占?
【发布时间】:2011-03-04 09:47:51
【问题描述】:

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

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

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

绑定非常标准:

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

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

【问题讨论】:

  • 你在 TargetUpdated 事件处理程序中做了什么特别的事情吗?
  • 我不知道这是否只是一个错字,但您在绑定中缺少逗号。它应该如下所示:{Binding Path=Total, Converter={StaticResource CurrencyToStringConverter}, NotifyOnTargetUpdated=True}
  • 这是一个错字,为了便于阅读,我在问题中添加了换行符,在真正的源代码中 Converter 和 NotifyOnTargetUpdated 部分之间有一个逗号。编辑问题以解决此问题。
  • 我在问题中添加了处理程序的代码。虽然它过于复杂,但我认为它不会做任何可能破坏绑定的事情。

标签: wpf data-binding exception ivalueconverter


【解决方案1】:

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

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

因此,它使用空的textBlock.Contenu 值访问您的事件处理程序,您将它传递给 FormattedText 的第一个参数(名为 textToFormat),它会抛出 ArgumentNullException。

在运行您的代码之前,练习一些防御性编程并检查您的 textBlock.Contenu 值是否为 null。

两个提示供日后参考:

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

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

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

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

【讨论】:

  • 谢谢,这正是问题所在。我根本没想到会在控件初始化期间被调用。
猜你喜欢
  • 2011-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 2016-03-10
  • 2013-04-02
  • 1970-01-01
相关资源
最近更新 更多