2009-05-20 12 views
80

El siguiente WPF UserControl llamó al DataTypeWholeNumber que funciona.¿Cómo puede un UserControl de WPF heredar un UserControl de WPF?

Ahora quiero hacer un control de usuario llama DataTypeDateTime y DataTypeEmail, etc.

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

Sin embargo, cuando lo hago, me sale el error : Declaración parcial no puede tener diferentes clases de base.

Entonces, ¿cómo puedo implementar la herencia con UserControls para que la funcionalidad compartida esté 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()); 



    } 
} 
+0

para la solución de WPF con herencia visual, consulte: http://svetoslavsavov.blogspot.gr/2009/09/user-control-inheritance-in-wpf.html o para definir explícitamente la GUI en el antecesor, vea http: // support.microsoft.com/kb/957231 –

Respuesta

114

Asegúrese de que ha cambiado la primera etiqueta en el XAML para heredar también de su nuevo BaseType

Así

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

convierte

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

Por lo tanto, 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ínalo para que herede directamente de Usercontrol.
  • Asegúrese de que la subclase hereda de la clase base tanto en el archivo cs de código subyacente como en la primera etiqueta de xaml (como se muestra arriba).
+3

cuando realizo ese cambio me sale el error: "... DataTypes.BaseDataType no puede ser la raíz de un archivo XAML porque se definió utilizando XAML", ¿cómo se sale de esto? ¿referencia circular? –

+9

Si solo puede hacer que la clase base sea un tipo normal que se hereda de UserControl sin definir ningún xmal (por lo que no se divide una clase parcial en dos archivos). El problema es que no puede heredar xmal, por lo que ni la clase base ni la clase hija necesitan tener un archivo xmal. O eso o haz que tus clases sean controles personalizados en lugar de controles de usuario. De esta forma, la apariencia se define fuera de la clase parcial, pero perderá la facilidad de uso de un Control de usuario. –

+1

Eso es todo: si haces de BaseDataType una clase normal que hereda UserControl, entonces funciona. Excelente, gracias. –

1

he encontrado la respuesta en este artículo: http://www.paulstovell.com/xmlnsdefinition

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

0

Me encontré con el mismo problema pero necesitaba heredar el control de una clase abstracta, que no es compatible con el diseñador. Lo que resolvió mi problema es hacer que el control de usuario herede de una clase estándar (que hereda UserControl) y 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
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>  
0

Hay definición de clase parcial creado por el diseñador, se puede abrir en forma fácil a través de InitializeComponent() definición del método. Luego simplemente cambie la legitimidad de clase parcial de UserControl a BaseDataType (o cualquiera que haya especificado en la definición de clase).

Después de eso, se advertirá que el método InitializeComponent() está oculto en la clase secundaria.

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

+0

No se puede convertir de Controls.Login a Controls.BaseControl. – Himilou

Cuestiones relacionadas