it-swarm.com.de

Wie kann ein WPF-Benutzersteuerelement ein WPF-Benutzersteuerelement erben?

Das folgende WPF-Benutzersteuerelement hat DataTypeWholeNumber aufgerufen und funktioniert.

Jetzt möchte ich ein UserControl namens DataTypeDateTime und DataTypeEmail usw. erstellen.

Viele der Abhängigkeitseigenschaften werden von all diesen Steuerelementen gemeinsam genutzt. Daher möchte ich ihre allgemeinen Methoden in einen BaseDataType einfügen und jedes dieser UserControls von diesem Basistyp erben lassen.

Dabei erhalte ich jedoch den Fehler : Partial Declaration darf keine unterschiedlichen Basisklassen haben .

Wie kann ich also die Vererbung mit UserControls implementieren, sodass die gemeinsame Funktionalität nur in der Basisklasse enthalten ist?

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

Stellen Sie sicher, dass Sie das erste Tag in der XAML so geändert haben, dass es auch von Ihrem neuen Basistyp erbt

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

wird

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

Um die vollständige Antwort einschließlich der zusätzlichen Details aus den Kommentaren unten zusammenzufassen:

  • Die Basisklasse sollte keine XAML-Datei enthalten. Definieren Sie es in einer einzelnen (nicht partiellen) cs-Datei und definieren Sie es so, dass es direkt von Usercontrol erbt.
  • Stellen Sie sicher, dass die Unterklasse von der Basisklasse sowohl in der cs-CodeBehind-Datei als auch im ersten Tag der XAML (wie oben gezeigt) erbt.
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

Ich fand die Antwort in diesem Artikel: http://www.paulstovell.com/xmlnsdefinition

Grundsätzlich heißt es, dass Sie in der Datei AssemlyInfo.cs einen XML-Namespace definieren sollten, der in der XAML verwendet werden kann. Es hat bei mir funktioniert, aber ich habe die Basisbenutzersteuerungsklasse in einer separaten DLL abgelegt ...

1
knee-cola

Ich bin auf dasselbe Problem gestoßen, musste aber das Steuerelement von einer abstrakten Klasse erben lassen, die vom Designer nicht unterstützt wird. Was mein Problem gelöst hat, ist, das Benutzersteuerelement von einer Standardklasse (die UserControl erbt) und einer Schnittstelle erben zu lassen. Auf diese Weise arbeitet der Designer.

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

Es gibt eine partielle Klassendefinition, die vom Designer erstellt wurde. Sie können sie auf einfache Weise über die Methodendefinition InitializeComponent () öffnen. Ändern Sie dann einfach die partielle Klassenheritenz von UserControl in BaseDataType (oder eine andere, die Sie in der Klassendefinition angegeben haben).

Danach erhalten Sie eine Warnung, dass die InitializeComponent () -Methode in der untergeordneten Klasse ausgeblendet ist.

Daher können Sie ein CustomControl als Basisklasse anstelle von UserControl definieren, um eine Teildefinition in der Basisklasse zu vermeiden (wie in einem Kommentar beschrieben).

0
Kakha Middle Or