【问题标题】:Getting an XamlObjectWriterException only at design time with ValueConverter inside DataTemplate (Visual Studio 2015)仅在设计时使用 DataTemplate 中的 ValueConverter 获取 XamlObjectWriterException (Visual Studio 2015)
【发布时间】:2017-01-14 13:45:09
【问题描述】:

我有一个在运行时完美运行但在设计时失败的应用程序 Collection property 'System.Windows.Data.Binding'.'ConverterParameter' is null exception.

我认为我已将其范围缩小到我在 DataTemplate 内的值转换器中引用 x:array 静态资源(在资源字典中声明,在 App.xaml 中合并)。

如果我在 DataTemplate 之外使用相同的代码,我不会遇到这个问题。 我怀疑this question 的根本原因是一样的。

我已经重现了这个问题:

在资源字典中:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:trial_app_for_x_array_issue.Resources">

<x:Array x:Key="VisibilityArrayFalseCollapsed" Type="Visibility">
    <Visibility>Visible</Visibility>
    <Visibility>Collapsed</Visibility>
</x:Array>

在数据转换器中:

using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace trial_app_for_x_array_issue.Converters
{
    public class BoolToVisibilityMultiParamConverter : IValueConverter

    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // Check for design mode.
            if ((bool)(DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue))
            {
                return Visibility.Visible;
            }

            if (value is bool && targetType == typeof(Visibility))
            {
                Array arr = parameter as Array;
                if (null != arr && arr.Length == 2)
                {
                    bool ValueEqTrue = (bool)value;
                    if (ValueEqTrue)
                    {
                        return arr.GetValue(0);
                    }
                    return arr.GetValue(1);
                }
            }
            return Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

在主窗口中:

<Window x:Class="trial_app_for_x_array_issue.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:converters="clr-namespace:trial_app_for_x_array_issue.Converters"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="525"
    Height="350">
<Window.Resources>
    <converters:BoolToVisibilityMultiParamConverter x:Key="MultiParamBoolToVisibilityConverter" />
</Window.Resources>
<Grid>
    <Expander>
        <Expander.HeaderTemplate>
            <DataTemplate>
                <TextBlock Name="CurrentActivityPercentageTextBlock"
                           HorizontalAlignment="Center"
                           VerticalAlignment="Center"
                           Text="Hello World"
                           Visibility="{Binding CurrentActivities.IsIndeterminate,
                                                Converter={StaticResource MultiParamBoolToVisibilityConverter},
                                                ConverterParameter={StaticResource VisibilityArrayFalseCollapsed}}" />

            </DataTemplate>
        </Expander.HeaderTemplate>
    </Expander>
</Grid>

如果我将 TextBox 从 DataTemplate 中取出,则不会出现错误。

顺便说一句,如果我使用另一种类型而不是 x:array,也不例外,因此(至少对我而言)这似乎与在 DataTemplate 中使用 x:array 资源有关。

我现在已经没有想法了......

【问题讨论】:

  • 如果你在 Parameter 类的 Parameter 属性的设置器上设置断点(你需要 dotpeek 作为符号服务器并设置函数断点)我怀疑你会发现它是设置两次:第一次使用正确的值,第二次使用 null。我认为XamlObjectWriter 类中存在错误。
  • 谢谢酷蓝,我现在就下载Dot peek试试看。 (这可能很“有趣”:我以前从未做过这种断点)
  • 嗯,嗨 CoolBlue,有没有机会告诉我你是怎么做到的?我已经设置了符号服务器,但在那之后,我有点卡住了。
  • 我在上面的 cmets 中给了你一个流浪汉,我试图回答你提到的另一个问题,也许这会对你有所帮助。同时,在您的情况下,绑定将失败,因为 HeaderTemplate 的数据上下文是 Expander 的 Header 属性,该属性为空,因此转换器不会触发。
  • 顺便说一下,here 是一些关于如何单步执行 wpf 源代码的信息。现在您已经设置了符号服务器,您应该能够执行此操作。此外,这个站点中有很多 WPF 源代码,如果您遇到困难,这些代码有时很有用。

标签: c# wpf app.xaml


【解决方案1】:

不幸的是,这看起来像是 XamlLoader 中的一个错误。它似乎很难将其各种解析上下文联系起来。
不是很干,但是您可以通过将数组移动到 DataTemplate 资源来修复它。我不确定您对 Visibility 的绑定做了什么(如我的评论中所述),因此我将 Expander.Header 属性设置为适当的值,以便为 DataTemplate 建立正确的数据上下文...

<Window x:Class="SO_41650679_2670182.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:converters="clr-namespace:SO_41650679_2670182.Converters"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <RelativeSource x:Key="View" Mode="FindAncestor"
                        AncestorType="{x:Type Window}" />
        <converters:BoolToVisibilityMultiParamConverter x:Key="MultiParamBoolToVisibilityConverter" />
    </Window.Resources>
    <StackPanel>
        <Expander Header="{Binding RelativeSource={StaticResource View}, Path=CurrentActivities.IsIndeterminate}">
            Hello World
            <Expander.HeaderTemplate>
                <DataTemplate>
                    <DataTemplate.Resources>
                        <x:Array x:Key="VisibilityArrayFalseCollapsed" Type="Visibility">
                            <Visibility>Visible</Visibility>
                            <Visibility>Collapsed</Visibility>
                        </x:Array>
                    </DataTemplate.Resources>
                    <TextBlock Name="CurrentActivityPercentageTextBlock"
                               HorizontalAlignment="Center"
                               VerticalAlignment="Center"
                               Text="Header"
                               Visibility="{Binding Converter={StaticResource MultiParamBoolToVisibilityConverter},
                                                ConverterParameter={StaticResource VisibilityArrayFalseCollapsed}}" />
                </DataTemplate>
            </Expander.HeaderTemplate>
        </Expander>
        <ToggleButton Name="ToggleButton" Height="30"
                      IsChecked="{Binding CurrentActivities.IsIndeterminate, 
                                  RelativeSource={StaticResource View}}" />
    </StackPanel>
</Window>

虽然这消除了设计时错误,但它会导致警告 No default constructor found for type 'System.Windows.Visibility[]'(我不知道这是什么问题……)而且您的设计时转换器代码路径似乎也不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    • 2016-11-14
    相关资源
    最近更新 更多