首页 文章

WPF:在另一个自定义控件的ItemTemplate中使用自定义控件时出错

提问于
浏览
0

我有一个自定义控件库,我在我的主应用程序中使用了几个自定义控件 . 我有一个简单的自定义控件,允许用户从组合框中选择笔厚度值 . 现在,我正在创建一个基于列表框的新自定义控件,我想在新的自定义控件的ItemTemplate中包含笔厚度组合框 .

我收到此错误:

"Cannot create instance of "LineThicknessComboBox" defined in assembly CustomControls ... Exception has been thrown by the target of an invocation. Error at object "10_T" in markup file 'CustomControls;component/Themes/CustomListBox.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可以正常工作 .

任何人都可以解释为什么我收到此错误?可以将我的自定义控件包含在另一个控件中,即使它们位于同一个自定义控件库中,对吗?

谢谢!

2 回答

  • 0

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

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

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

    来自MSDN

  • 1

    您可能遇到了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)));
    
            }
        }
    }
    

相关问题