Pergunta

Eu tenho uma biblioteca de controle personalizada, onde tenho vários controles personalizados que uso no meu aplicativo principal. Eu tenho um controle personalizado simples que permite que o usuário selecione valores de espessura da caneta de um ComboBox. Agora, estou criando um novo controle personalizado, com base em uma caixa de listagem, e quero incluir o ComboBoBox de espessura da caneta no novo ItemTemplate do novo controle personalizado.

Estou recebendo este erro:

"Não é possível criar a instância de" LinethicknessComboBox "definido nos montagens de montagem, a exceção foi lançada pelo alvo de uma invocação. Erro no objeto" 10_T "no arquivo de marcação 'CustomControls; component/temes/customlistbox.general.xaml'.

Aqui está o xaml e o código por trás do LinethicknessComboBox:

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

        }
    }
}

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

Aqui está o XAML e o CodeBehind para o meu novo Lista CustomListBox:

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

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

E aqui está o meu 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>

Estou pensando que tenho algum tipo de problema de referência, mas não consigo descobrir o que está errado. O programa compila e é executado sem nenhum aviso/erros, mas quando o ListBox CustomList é criado no meu aplicativo principal, recebo o erro listado acima. Sem incluir o LinethicknessComboBox, o ListBox CustomList funciona bem.

Alguém pode explicar por que estou recebendo esse erro? É possível incluir meu controle personalizado em outro, mesmo que eles estejam na mesma biblioteca de controle personalizada, correto?

Obrigado!

Foi útil?

Solução

// Acho que deve ser o construtor estático em ambos os casos, porque a substituição dos metadados da propriedade de dependência deve sempre ser feita no construtor estático.

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

Chamadas para Overidemetadata deve ser executado apenas dentro dos construtores estáticos do tipo que se fornece como o parâmetro do quinto e o método ou por meio de instanciação semelhante. Tentar alterar metadados após a existência de instâncias do tipo de proprietário não aumentará exceções, mas resultará em comportamentos inconsistentes no sistema de propriedades.

De msdn

Outras dicas

Você pode estar enfrentando um problema com o DesignMode e o código no seu construtor. Não posso dizer com certeza, pois tive meu quinhão de problemas com os controles do usuário do WPF e a superfície do design, e todos eles têm erros enigmáticos como este.

A solução é usar a classe System.ComponentModel.DesignerProperties para verificar se você está no modo de design e envolver qualquer código que não funcione no modo de design em um bloco IF para impedir que ele seja executado:

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

        }
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top