【问题标题】:WPF: Error using a custom control in the ItemTemplate of another custom controlWPF:在另一个自定义控件的 ItemTemplate 中使用自定义控件时出错
【发布时间】:2009-10-18 19:07:55
【问题描述】:

我有一个自定义控件库,其中有几个在我的主应用程序中使用的自定义控件。我有一个简单的自定义控件,可让用户从组合框中选择笔粗细值。现在,我正在创建一个基于列表框的新自定义控件,并且我想在新自定义控件的 ItemTemplate 中包含笔粗细组合框。

我收到此错误:

“无法创建在程序集 CustomControls 中定义的“LineThicknessComboBox”实例...调用的目标已引发异常。标记文件“CustomControls;component/Themes/CustomListBox”中的对象“10_T”出错。 General.xaml'。

这是 LineThicknessComboBox 的 XAML 和代码:

namespace CustomControls
{
    public class LineThicknessComboBox : ComboBox
    {
        public LineThicknessComboBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(LineThicknessComboBox)
                        , new FrameworkPropertyMetadata(typeof(LineThicknessComboBox)));

        }
    }
}

在 LineThicknessCombobox.Generic.xaml 中:

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

<Style TargetType="{x:Type local:LineThicknessComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                ...
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

</ResourceDictionary>

这是我的新 CustomListBox 的 XAML 和代码隐藏:

namespace CustomControls
{
    public class CustomListBox : ListBox
    {
        public CustomListBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomListBox)
                        , new FrameworkPropertyMetadata(typeof(CustomListBox)));
        }
    }
}

在 CustomListBox.Generic.xaml 中:

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

<Style TargetType="{x:Type local:CustomListBox}" BasedOn="{StaticResource {x:Type ListBox}}">
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <Border>
                 ...
                     <local:LineThicknessComboBox />
                 ...  
                </Border>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

</ResourceDictionary>

这是我的 Generix.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="CustomControls;component/Themes/LineThicknessComboBox.Generic.xaml"/>
        <ResourceDictionary Source="CustomControls;component/Themes/CustomListBox.Generic.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

我在想我有某种参考问题,但不知道哪里出了问题。该程序编译并运行时没有任何警告/错误,但是在我的主应用程序中创建 CustomListBox 时,我收到上面列出的错误。如果不包括 LineThicknessComboBox,CustomListBox 可以正常工作。

谁能解释我为什么会收到这个错误?可以将我的自定义控件包含在另一个控件中,即使它们在同一个自定义控件库中,对吗?

谢谢!

【问题讨论】:

  • "调用的目标抛出了异常。"深入了解 InnerException(您可能需要深入了解不止一个级别),您应该会找到一个更有意义的异常。一旦你看到它,这可能会使错误变得明显,或者如果你可以发布它,它会帮助诊断。

标签: c# wpf user-controls custom-controls resourcedictionary


【解决方案1】:

// 我认为在这两种情况下它都应该是静态构造函数,因为依赖属性元数据覆盖必须始终在静态构造函数中完成。

// not public LineThicknessComboBox()
static LineThicknessComboBox()        
{
            DefaultStyleKeyProperty.OverrideMetadata(
               typeof(LineThicknessComboBox)
                        , new FrameworkPropertyMetadata(
                              typeof(LineThicknessComboBox)));
}

OverrideMetadata 的调用只能在提供自身作为此方法的forType 参数的类型的静态构造函数中执行,或者通过类似的实例化执行。在所有者类型的实例存在后尝试更改元数据不会引发异常,但会导致属性系统中的行为不一致。

来自 MSDN

【讨论】:

  • 我会在今天晚些时候回家时试一试。感谢您的提醒,我不确定为什么我的构造函数没有声明为静态的。
【解决方案2】:

您可能在使用 DesignMode 时遇到问题,并且您的构造函数中的代码可能会遇到问题。我不能肯定地说,因为我在 WPF 用户控件和设计界面方面遇到了相当多的问题,而且所有这些问题都有这样的神秘错误。

解决方案是使用 System.ComponentModel.DesignerProperties 类检查您是否处于设计模式,并将任何在设计模式下不起作用的代码包装在 if 块中以防止其运行:

namespace CustomControls
{
    public class LineThicknessComboBox : ComboBox
    {
        public LineThicknessComboBox()
        {
            // Design-mode capable code...

            if (DesignerProperties.GetIsInDesignMode(this)) return;

            // Design mode incapable code...

            DefaultStyleKeyProperty.OverrideMetadata(typeof(LineThicknessComboBox)
                        , new FrameworkPropertyMetadata(typeof(LineThicknessComboBox)));

        }
    }
}

【讨论】:

  • 我不认为这是我的问题,因为我在运行时遇到错误。不过感谢您的回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多