Как WPF UserControl наследует WPC UserControl?
Следующий пользовательский элемент управления WPF называется DataTypeWholeNumber, который работает.
Теперь я хочу создать UserControl с именем DataTypeDateTime и DataTypeEmail и т.д.
Многие из свойств зависимостей будут совместно использоваться всеми этими элементами управления, и поэтому я хочу поместить их общие методы в BaseDataType, и каждый из этих UserControls наследует от этого базового типа.
Однако, когда я это делаю, я получаю ошибку: Partial Declaration может не иметь разных базовых классов.
Итак, как я могу реализовать наследование с помощью 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());
}
}
Ответы
Ответ 1
Убедитесь, что вы изменили первый тег в 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 code-behind, так и в первом теге xaml (как показано выше).
Ответ 2
Я нашел ответ в этой статье: http://www.paulstovell.com/xmlnsdefinition
В основном говорится, что вы должны определить пространство имен XML в файле AssemlyInfo.cs, которое можно использовать в XAML. Он работал у меня, однако я поместил базовый пользовательский класс управления в отдельную DLL...
Ответ 3
Я столкнулся с той же проблемой, но мне нужно было наследовать элемент управления от абстрактного класса, который не поддерживается дизайнером. То, что решило мою проблему, - это наследование 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)
}
Ответ 4
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>
Ответ 5
Существует частичное определение класса, созданное дизайнером, вы можете легко открыть его с помощью определения метода InitializeComponent().
Затем просто измените частичный класс iheritence с UserControl на BaseDataType (или любой, указанный вами в определении класса).
После этого у вас будет предупреждение о том, что метод InitializeComponent() скрыт в дочернем классе.
Поэтому вы можете сделать CustomControl как базовую класку вместо UserControl, чтобы избежать частичного определения в базовом классе (как описано в одном комментарии).