2009-05-20 21 views
80

Di seguito WPF UserControl chiamato DataTypeWholeNumber che funziona.In che modo un UserControl WPF eredita un UserControl WPF?

Ora voglio fare un controllo utente chiamato DataTypeDateTime e DataTypeEmail, ecc

Molte delle proprietà di dipendenza saranno condivisi da tutti questi controlli, e quindi voglio mettere loro metodi comuni in un BaseDataType e ognuno di questi UserControls eredita da questo tipo di base.

Tuttavia, quando lo faccio, ottengo l'errore : Dichiarazione parziale non può avere diverse classi di base.

Così come posso implementare eredità con controlli utente in modo condiviso la funzionalità è tutta nella classe di 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

per la soluzione WPF con ereditarietà visiva: http://svetoslavsavov.blogspot.gr/2009/09/user-control-inheritance-in-wpf.html o per la definizione esplicita della GUI nell'antenato, consultare http: // support.microsoft.com/kb/957231 –

risposta

114

Assicurarsi che è stato modificato il primo tag nel codice XAML di ereditare anche dal vostro nuovo BaseType

Così

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

diventa

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

Quindi, per riassumere la risposta completa incluso i dettagli aggiuntivi dei commenti seguenti:

  • La classe di base non dovrebbe includere un file xaml. Definirlo in un unico file cs (non parziale) e definirlo per ereditare direttamente da Usercontrol.
  • Assicurarsi che la sottoclasse eredita dalla classe base sia nel code-behind cs file che nel primo tag del XAML (come indicato sopra).
+3

quando apporto la modifica ottengo l'errore: "... DataTypes.BaseDataType non può essere la radice di un file XAML perché è stata definita utilizzando XAML", come si esce da questo riferimento circolare? –

+9

Se si può semplicemente rendere la classe base un tipo normale che eredita da UserControl senza definire alcun xmal (quindi non una divisione parziale della classe su due file). Il problema è che non puoi ereditare xmal, quindi la classe base o quella figlio non devono avere un file xmal. In alternativa, oppure imposta i controlli personalizzati delle classi anziché i controlli utente. In questo modo l'aspetto è definito al di fuori della classe parziale ma perderai la facilità d'uso di un controllo utente. –

+1

Ecco fatto: se si rende BaseDataType una normale classe che eredita UserControl, allora funziona. Eccellente grazie. –

1

ho trovato la risposta in questo articolo: http://www.paulstovell.com/xmlnsdefinition

Fondamentalmente ciò che è dice è che si dovrebbe definire un namespace XML nel file AssemlyInfo.cs, il che può essere utilizzato nel XAML. Ha funzionato per me, tuttavia ho inserito la classe di controllo utente di base in una DLL separata ...

0

Ho riscontrato lo stesso problema ma era necessario che il controllo ereditasse da una classe astratta, che non è supportata dal progettista. Ciò che ha risolto il mio problema è che l'usercontrol eredita sia da una classe standard (che eredita UserControl) sia da un'interfaccia. In questo modo il designer sta lavorando.

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

C'è definizione parziale classe creata dal designer, è possibile aprirlo modo semplice tramite InitializeComponent() definizione di metodo. Poi basta cambiare iheritence classe parziale da UserControl a BaseDataType (o qualsiasi specificata durante la definizione della classe).

Dopo che avrete avvertimento che il metodo InitializeComponent() è nascosto nella classe figlio.

Pertanto è possibile creare un CustomControl come base clas anziché UserControl per evitare la definizione parziale nella classe base (come descritto in un commento).

+0

Impossibile convertire da Controls.Login in Controls.BaseControl. – Himilou

Problemi correlati