仅在设计时使用DataTemplate内部的ValueConverter获取XamlObjectWriterException(Visual Studio 2015) [英] Getting an XamlObjectWriterException only at design time with ValueConverter inside DataTemplate (Visual Studio 2015)

查看:113
本文介绍了仅在设计时使用DataTemplate内部的ValueConverter获取XamlObjectWriterException(Visual Studio 2015)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可以在运行时完美运行的应用程序,但在设计时却失败了,并且具有集合属性'System.Windows.Data.Binding'.'ConverterParameter'为空异常.

I have an application which runs perfectly at run-time but fails at design time with Collection property 'System.Windows.Data.Binding'.'ConverterParameter' is null exception.

我认为我已将其缩小为以下事实:我正在DataTemplate内部的值转换器中引用x:array静态资源(在资源字典中声明,在App.xaml中合并).

I think I have narrowed it down to the fact that I am referencing an x:array static resource (declared in resource dictionary, merged in App.xaml) in a value converter inside a DataTemplate.

如果在DataTemplate外部使用相同的代码,则不会出现此问题. 我怀疑此问题具有相同的根本原因

If I use the same code outside a DataTemplate, I do not get this problem. I suspect that this question has the same root cause.

我已经重新创建了问题:

I have re-created the problem:

在资源词典中:

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

在DataConverter中:

In the DataConverter:

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

和在MainWindow中:

and in MainWindow:

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

如果我从DataTemplate中取出TextBox,则没有错误.

If I take the TextBox out of the DataTemplate, there are no errors.

顺便说一句,如果我使用其他类型而不是x:array,也没有例外,因此(至少在我看来)与使用DataTemplate中的x:array资源有关.

Incidentally, if I use another type instead of x:array, there is no exception so it seems (to me at least) to be something to do with the use of x:array resource inside a DataTemplate.

我现在已经没有主意了...

I have now run out of ideas ...

推荐答案

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

Unfortunately this looks like a bug in the XamlLoader. It seems to struggle with linking its various parsing contexts.
Not very Dry but, you can fix it by moving the array to the DataTemplate Resources. I'm not sure what you were doing with the binding for Visibility (as mentioned in my comment) so I set the Expander.Header property to an appropriate value in order to establish the correct data context for the 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[]'(我不知道这是什么问题...),而且您的设计时转换器代码路径似乎也不起作用.

Although this gets rid of the design time error, it causes a warning about No default constructor found for type 'System.Windows.Visibility[]' (I have no idea what it's problem is...) and your design time converter code path doesn't seem to work either.

这篇关于仅在设计时使用DataTemplate内部的ValueConverter获取XamlObjectWriterException(Visual Studio 2015)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆