来自 Java,当涉及到制作 GUI 组件时,我真的习惯了一种常见的做法:我通常会做某种基类,其中包含我的 GUI 组件的所有常见对象,然后我扩展它。
所以,基本上,这就是我想用 C# 和 XAML 实现的目标。
为了使问题更清楚,这是我正在做的一个例子(那是行不通的!):
我们有一个带有自己的 XAML 的基类
<UserControl x:Class="BaseClass"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<Border BorderBrush="Aqua" BorderThickness="10" CornerRadius="10" x:Name="Border" HorizontalAlignment="Left" Height="480" VerticalAlignment="Top" Width="480"/>
</Grid>
</UserControl>
然后我们有一个扩展第一个类的类
<base:BaseClass x:Class="DerivedClass"
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:base="clr-namespace:BaseClass"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="60" d:DesignWidth="200">
<Grid x:Name="LayoutRoot" Margin="0" Width="200" Height="60" MaxWidth="200" MaxHeight="60" Background="{StaticResource PhoneAccentBrush}">
<TextBlock x:Name="dummyText" HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="Dummy Plugin" VerticalAlignment="Top" Height="40" Width="180" Foreground="White" TextAlignment="Center"/>
</Grid>
</base:BaseClass>
从 2 个 XAML 代码开始,我想做的就是将其DerivedClass
放入BaseClass
容器中。这将允许我在各种派生类之间共享组件,而无需每次需要时都编写代码。
例如,如果我希望我的所有组件都具有圆形边框,我只想将它放在贝司类中,然后将它放在所有派生类中,而无需重写它。
当然,每个 c# 类都有自己的InitializeComponent()
方法,这可能意味着派生组件将通过删除基类的方法来构建自己的内容。
即使在派生类中,从构造函数中删除该方法DerivedClass
也会为我提供基本内容,但是,当然,我丢失了我在DerivedClass
.
从 调用基本构造函数DerivedClass
没有任何效果,因为它是在派生之前调用的InitializeComponent()
。
所以问题是:如何在不破坏派生类的 XAML 设计的情况下将基类的 XAML 设计用于派生类?有什么方法可以简单地将内容添加到基类,同时仍然与设计器本身合作?
(我知道我可以删除派生类的 XAML 并通过代码执行我想要执行的操作,但我想知道我是否可以仅与设计器一起执行此操作,因为我不想在有的时候编写我的 GUI有设计师)
编辑:
在 HighCore 的回复之后,我做了一些适用于 Windows Phone 的操作,但我不确定我做的是否正确(是的,它有效,但可能只是错了!)。
这是我所做的:
BaseControl.xaml
<UserControl x:Class="TestInheritance.BaseControl"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<TextBlock HorizontalAlignment="Center">BASE</TextBlock>
<ContentPresenter Name="Presenter" Content="{Binding PresenterContent}"/>
</Grid>
</UserControl>
BaseControl.xaml.cs
namespace TestInheritance
{
public partial class BaseControl : UserControl
{
public Grid PresenterContent { get; set; }
public BaseControl()
{
DataContext = this;
InitializeComponent();
}
}
}
派生控件.xaml
<local:BaseControl x:Class="TestInheritance.DerivedControl"
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:local="clr-namespace:TestInheritance"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<local:BaseControl.PresenterContent>
<Grid>
<TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Center">DERIVED</TextBlock>
</Grid>
</local:BaseControl.PresenterContent>
</local:BaseControl>
请注意,这DerivedClass
是一个实例,BaseClass
因为出于其他原因,我需要它们具有一些通用属性/方法。
你觉得我的解决方案怎么样?是否有意义?