Następująca kontrola użytkownika WPF o nazwie DataTypeWholeNumber, która działa.
Teraz chcę utworzyć kontrolę użytkownika o nazwie DataTypeDateTime i DataTypeEmail itp.
Wiele właściwości zależności będzie współużytkowanych przez wszystkie te kontrolki, dlatego chcę umieścić ich wspólne metody w BaseDataType i aby każda z tych kontrolek użytkownika dziedziczyła z tego typu podstawowego.
Jednak gdy to robię, pojawia się błąd: Deklaracja częściowa może nie mieć różnych klas bazowych .
Jak więc zaimplementować dziedziczenie za pomocą UserControls, aby wspólna funkcjonalność znajdowała się w klasie bazowej?
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());
}
}
c#
wpf
xaml
user-controls
Edward Tanguay
źródło
źródło
Odpowiedzi:
Upewnij się, że zmieniłeś pierwszy znacznik w xaml, aby dziedziczył również z nowego typu podstawowego
Więc
<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" >
staje się
<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" >
Podsumowując pełną odpowiedź, w tym dodatkowe szczegóły z poniższych komentarzy:
źródło
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>
źródło
Odpowiedź znalazłem w tym artykule: http://www.paulstovell.com/xmlnsdefinition
Zasadniczo mówi się, że należy zdefiniować przestrzeń nazw XML w pliku AssemlyInfo.cs, której można użyć w pliku XAML. U mnie zadziałało, jednak podstawową klasę kontroli użytkownika umieściłem w osobnej bibliotece DLL ...
źródło
Napotkałem ten sam problem, ale musiałem mieć kontrolę dziedziczącą z klasy abstrakcyjnej, która nie jest obsługiwana przez projektanta. To, co rozwiązało mój problem, to spowodowanie, że kontrola użytkownika dziedziczy zarówno klasę standardową (która dziedziczy UserControl), jak i interfejs. W ten sposób pracuje projektant.
//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) }
źródło
Istnieje częściowa definicja klasy utworzona przez projektanta, którą można łatwo otworzyć za pomocą definicji metody InitializeComponent (). Następnie po prostu zmień częściowe iheritence klasy z UserControl na BaseDataType (lub dowolną określoną w definicji klasy).
Następnie pojawi się ostrzeżenie, że metoda InitializeComponent () jest ukryta w klasie potomnej.
Dlatego możesz ustawić CustomControl jako klasę podstawową zamiast UserControl, aby uniknąć częściowej definicji w klasie bazowej (jak opisano w jednym komentarzu).
źródło