web-dev-qa-db-fra.com

Comment un WPF UserControl peut-il hériter d'un WPF UserControl?

Le WPF UserControl suivant appelé DataTypeWholeNumber qui fonctionne.

Maintenant, je veux créer un UserControl appelé DataTypeDateTime et DataTypeEmail, etc.

Beaucoup de propriétés de dépendance seront partagées par tous ces contrôles et je veux donc mettre leurs méthodes communes dans un BaseDataType et que chacun de ces UserControls hérite de ce type de base.

Cependant, lorsque je fais cela, j'obtiens l'erreur : la déclaration partielle peut ne pas avoir différentes classes de base .

Alors, comment puis-je implémenter l'héritage avec UserControls afin que les fonctionnalités partagées soient toutes dans la classe de 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());



    }
}
83
Edward Tanguay

Assurez-vous que vous avez modifié la première balise dans le xaml pour hériter également de votre nouveau type de base

Alors

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

devient

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

Donc, pour résumer la réponse complète, y compris les détails supplémentaires des commentaires ci-dessous:

  • La classe de base ne doit pas inclure de fichier xaml. Définissez-le dans un seul fichier cs (non partiel) et définissez-le pour hériter directement d'Usercontrol.
  • Assurez-vous que la sous-classe hérite de la classe de base à la fois dans le fichier code-behind cs et dans la première balise de xaml (comme illustré ci-dessus).
120
Martin Harris
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
Petar

J'ai trouvé la réponse dans cet article: http://www.paulstovell.com/xmlnsdefinition

Fondamentalement, ce qui est dit, c'est que vous devez définir un espace de noms XML dans le fichier AssemlyInfo.cs, qui peut être utilisé dans le XAML. Cela a fonctionné pour moi, mais j'ai placé la classe de contrôle utilisateur de base dans une DLL distincte ...

1
knee-cola

J'ai rencontré le même problème mais j'avais besoin que le contrôle hérite d'une classe abstraite, qui n'est pas prise en charge par le concepteur. Ce qui a résolu mon problème, c'est que l'héritier usercontrol hérite à la fois d'une classe standard (qui hérite de UserControl) et d'une interface. De cette façon, le concepteur travaille.

//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
Sam L.

Il existe une définition de classe partielle créée par le concepteur, vous pouvez l'ouvrir facilement via la définition de la méthode InitializeComponent (). Ensuite, changez simplement l'héritage de classe partiel de UserControl en BaseDataType (ou tout autre que vous avez spécifié dans la définition de classe).

Après cela, vous aurez un avertissement indiquant que la méthode InitializeComponent () est masquée dans la classe enfant.

Par conséquent, vous pouvez créer un CustomControl en tant que clas de base au lieu de UserControl pour éviter une définition partielle dans la classe de base (comme décrit dans un commentaire).

0
Kakha Middle Or