¿Cómo puede un WPF UserControl heredar un WPF UserControl?


El siguiente WPF UserControl llamado DataTypeWholeNumber que funciona.

Ahora quiero hacer un UserControl llamado DataTypeDateTime y DataTypeEmail, etc.

Muchas de las Propiedades de dependencia serán compartidas por todos estos controles y por lo tanto quiero poner sus métodos comunes en un BaseDataType y hacer que cada uno de estos UserControls herede de este tipo base.

Sin embargo, cuando hago eso, obtengo la error: Parcial La declaración no puede tener clases base diferentes.

Entonces, ¿cómo puedo implementar la herencia con UserControls para que la funcionalidad compartida esté toda en la clase base?

using System.Windows;
using System.Windows.Controls;

namespace TestDependencyProperty827.DataTypes
{
    public partial class DataTypeWholeNumber : BaseDataType
    {
        public DataTypeWholeNumber()
        {
            InitializeComponent();
            DataContext = this;

            //defaults
            TheWidth = 200;
        }

        public string TheLabel
        {
            get
            {
                return (string)GetValue(TheLabelProperty);
            }
            set
            {
                SetValue(TheLabelProperty, value);
            }
        }

        public static readonly DependencyProperty TheLabelProperty =
            DependencyProperty.Register("TheLabel", typeof(string), typeof(BaseDataType),
            new FrameworkPropertyMetadata());


        public string TheContent
        {
            get
            {
                return (string)GetValue(TheContentProperty);
            }
            set
            {
                SetValue(TheContentProperty, value);
            }
        }

        public static readonly DependencyProperty TheContentProperty =
            DependencyProperty.Register("TheContent", typeof(string), typeof(BaseDataType),
            new FrameworkPropertyMetadata());


        public int TheWidth
        {
            get
            {
                return (int)GetValue(TheWidthProperty);
            }
            set
            {
                SetValue(TheWidthProperty, value);
            }
        }

        public static readonly DependencyProperty TheWidthProperty =
            DependencyProperty.Register("TheWidth", typeof(int), typeof(DataTypeWholeNumber),
            new FrameworkPropertyMetadata());



    }
}
Author: Askolein, 2009-05-20

5 answers

Asegúrese de haber cambiado la primera etiqueta en el xaml para heredar también de su nuevo basetype

So

<UserControl x:Class="TestDependencyProperty827.DataTypes.DataTypeWholeNumber"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:s="clr-namespace:System;assembly=mscorlib"
    >

Se convierte en

<myTypes:BaseDataType x:Class="TestDependencyProperty827.DataTypes.DataTypeWholeNumber"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:s="clr-namespace:System;assembly=mscorlib"
    xmlns:myTypes="clr-namespace:TestDependencyProperty827.DataTypes"
    >

Así que, para resumir la respuesta completa incluyendo los detalles adicionales de los comentarios a continuación:

  • La clase base no debe incluir un archivo xaml. Defínelo en un único archivo cs (no parcial) y defínelo para heredarlo directamente de Usercontrol.
  • Asegúrese de que la subclase hereda de la clase base tanto en el cs código detrás del archivo y en la primera etiqueta del xaml (como se muestra arriba).
 115
Author: Martin Harris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-02 16:41:33
public partial class MooringConfigurator : MooringLineConfigurator
    {
        public MooringConfigurator()
        {
            InitializeComponent();
        }
    }



<dst:MooringLineConfigurator x:Class="Wave.Dashboards.Instruments.ConfiguratorViews.DST.MooringConfigurator"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:dst="clr-namespace:Wave.Dashboards.Instruments.ConfiguratorViews.DST"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">

    </Grid>
</dst:MooringLineConfigurator>    
 2
Author: Petar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-31 09:07:55

Encontré la respuesta en este artículo: http://www.paulstovell.com/xmlnsdefinition

Básicamente lo que se dice es que debe definir un espacio de nombres XML en el AssemlyInfo.archivo cs, que puede ser utilizado en el XAML. Funcionó para mí, sin embargo, coloqué la clase de control de usuario base en una DLL separada...

 1
Author: knee-cola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-30 21:52:34

Me encontré con el mismo problema, pero necesitaba que el control heredara de una clase abstracta, que no es compatible con el diseñador. Lo que resolvió mi problema es hacer que el usercontrol herede tanto de una clase estándar (que hereda UserControl) como de una interfaz. De esta manera el diseñador está trabajando.

//the xaml
<local:EcranFiche x:Class="VLEva.SIFEval.Ecrans.UC_BatimentAgricole" 
                  xmlns:local="clr-namespace:VLEva.SIFEval.Ecrans"
                  ...>
    ...
</local:EcranFiche>

// the usercontrol code behind
public partial class UC_BatimentAgricole : EcranFiche, IEcranFiche
{
    ...
}

// the interface
public interface IEcranFiche
{
   ...
}

// base class containing common implemented methods
public class EcranFiche : UserControl
{
    ... (ex: common interface implementation)
}
 0
Author: Sam L.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-12 14:32:13

Hay una definición de clase parcial creada por designer, puede abrirla fácilmente a través de la definición del método InitializeComponent (). A continuación, simplemente cambie partial class iheritence de UserControl a BaseDataType (o cualquiera que haya especificado en la definición de clase).

Después de eso, tendrá una advertencia de que el método InitializeComponent() está oculto en la clase hija.

Por lo tanto, puede hacer un CustomControl como clases base en lugar de UserControl para evitar la definición parcial en la clase base (como se describe en un comentario).

 0
Author: Kakha Middle Or,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-10 09:20:29