Как в WPF UserControl с наследование в WPF элемент управления UserControl?


следующий элемент управления WPF называется DataTypeWholeNumber который работает.

теперь я хочу сделать UserControl под названием DataTypeDateTime и DataTypeEmail и т. д.

многие свойства зависимостей будут совместно использоваться всеми этими элементами управления, и поэтому я хочу поставить их общие методы в BaseDataType и каждый из этих UserControls наследуется от этого базового типа.

однако, когда я сделайте это, я получаю ошибка: частичное объявление может не иметь различных базовых классов.

Итак,как я могу реализовать наследование с помощью UserControls, чтобы общая функциональность была в базовом классе?

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());



    }
}
5 81

5 ответов:

убедитесь, что вы изменили первый тег в XAML, чтобы наследовать от вашего нового базового типа

Так

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

становится

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

Итак, подводя итог полный ответ, включая дополнительные детали из комментариев ниже:

  • базовый класс не должен включать файл xaml. Определите его в одном (неполном) cs-файле и определите его для наследования непосредственно от Usercontrol.
  • убедитесь, что подкласс наследует от базового класса как в файле кода cs, так и в первом теге xaml (как показано выше).
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>    

Я нашел ответ в этой статье: http://www.paulstovell.com/xmlnsdefinition

в основном то, что говорит, что вы должны определить пространство имен XML в AssemlyInfo.cs-файл, который может быть использован в XAML. Это сработало для меня, однако я поместил базовый класс пользовательского элемента управления в отдельную DLL...

я столкнулся с той же проблемой, но мне нужно было наследовать элемент управления от абстрактного класса, который не поддерживается дизайнером. То, что решило мою проблему, делает usercontrol наследуемым как от стандартного класса (который наследует UserControl), так и от интерфейса. Таким образом дизайнер работает.

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

существует частичное определение класса, созданное дизайнером, вы можете легко открыть его с помощью определения метода InitializeComponent (). Затем просто измените частичный класс iheritence с UserControl на BaseDataType (или любой, указанный в определении класса).

после этого вы будете иметь предупреждение, что InitializeComponent() метод скрыт в дочернем классе.

вы можете сделать пользовательский элемент управления, как базовый клас, а не элемент управления UserControl, чтобы избежать частичного определения в базовом классе (как описано в одном комментарии).