C# XAML用户控制继承
来自Java,在制作GUI组件时,我已经习惯了一种常见的做法:我通常做一些基类,其中包含GUI组件的所有公共对象,然后对其进行扩展 因此,基本上,这就是我希望通过C#和XAML实现的目标 为了让问题更清楚,这里有一个我正在做的例子(不起作用!): 我们有一个拥有自己XAML的基类C# XAML用户控制继承,c#,wpf,xaml,inheritance,windows-phone-8,C#,Wpf,Xaml,Inheritance,Windows Phone 8,来自Java,在制作GUI组件时,我已经习惯了一种常见的做法:我通常做一些基类,其中包含GUI组件的所有公共对象,然后对其进行扩展 因此,基本上,这就是我希望通过C#和XAML实现的目标 为了让问题更清楚,这里有一个我正在做的例子(不起作用!): 我们有一个拥有自己XAML的基类 <UserControl x:Class="BaseClass" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
<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>
BaseControl.xaml.cs
namespace TestInheritance
{
public partial class BaseControl : UserControl
{
public Grid PresenterContent { get; set; }
public BaseControl()
{
DataContext = this;
InitializeComponent();
}
}
}
DerivedControl.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>
<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
的一个实例,因为出于其他原因,我需要它们具有一些公共属性/方法
你觉得我的解决方案怎么样?这有意义吗?据我所知,按原样派生UI是不可用的,除非用于资源XAML(ex的样式)。 可能是因为UI管理器无法猜测将扩展XAML代码放在何处: 设想基本UI如下所示:
<UserControl >
<Grid>
<Border/>
</Grid>
</UserControl>
以及派生UI:
<UserControl>
<DockPanel>
<Button/>
</DockPanel>
</UserControl>
混合后会有什么结果?直截了当的答案可能是:
<UserControl >
<Grid>
<Border/>
</Grid>
<DockPanel>
<Button/>
</DockPanel>
</UserControl>
这是不可能的
关于控件嵌入/兼容性问题呢?
好的,让我把它分成几个部分: 来自爪哇 忘记java吧。这是一种非常古老的语言,自90年代以来就没有进化过。C#是现在的一百万倍,WPF是目前最好的UI框架 据我所见,像swing这样的JavaUI框架在概念上类似于.Net的winforms,后者也被WPF所取代 WPF(及其基于XAML的兄弟)与周围的任何其他框架都有根本的不同,因为它们增强了通过定制和支持的功能 因此,在WPF上启动时需要一个
我通常做一些基类,它包含了所有常见的 对象,然后扩展它 在WPF中,通过引入“将任何内容放在任何内容中”的功能,可以消除对继承和其他臃肿的不必要的实践的需求 例如,
按钮可以这样定义:
<Button>
<Button.Content>
<StackPanel Orientation="Horizontal">
<Ellipse Fill="Red" Height="10" Width="10" Margin="2"/>
<TextBlock Text="Click Me"/>
</StackPanel>
<Button.Content>
</Button>
//Declaration of the System.Windows.Control.ContentControl class,
//inside the PresentationFramework.dll assembly
//...
[ContentProperty("Content")]
public class ContentControl: Control //...
{
//...
}
<Window>
<my:BaseClass>
<Border Background="Gray" BorderBrush="Blue" BorderThickness="2"
VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="Im the Hosted Content" Foreground="AliceBlue"/>
</Border>
</my:BaseClass>
</Window>
这意味着以下XAML在功能上与上述XAML相同:
<Button>
<StackPanel Orientation="Horizontal">
<Ellipse Fill="Red" Height="10" Width="10" Margin="2"/>
<TextBlock Text="Click Me"/>
</StackPanel>
</Button>
然后您可以像这样重用此模板:
<Button>
<Button.Content>
<StackPanel Orientation="Horizontal">
<Ellipse Fill="Red" Height="10" Width="10" Margin="2"/>
<TextBlock Text="Click Me"/>
</StackPanel>
<Button.Content>
</Button>
//Declaration of the System.Windows.Control.ContentControl class,
//inside the PresentationFramework.dll assembly
//...
[ContentProperty("Content")]
public class ContentControl: Control //...
{
//...
}
<Window>
<my:BaseClass>
<Border Background="Gray" BorderBrush="Blue" BorderThickness="2"
VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="Im the Hosted Content" Foreground="AliceBlue"/>
</Border>
</my:BaseClass>
</Window>
由于数据绑定,在WPF中完全不需要这样的东西
在UI中显示数据时实现高度灵活性的另一个概念是WPF,它允许您定义在屏幕上“呈现”某些数据类型时使用的特定UI
由于以上所有原因,WPF与大多数UI框架有着根本的不同,因此不再需要其他框架中常见的可怕的样板文件和黑客
我建议您阅读所有提供的链接,并在定义应用程序的结构和UI时记住所有这些概念和实践
如果您需要进一步的帮助,请告诉我。首先感谢您的回复!当我花时间阅读和理解你所写的内容时,我有一个简单的问题:是否所有的东西都能与Windows Phone一起工作,还是存在一些“仅限于桌面”的东西?@StepTNT WPF、Silverlight、WinRT和Windows Phone之间的XAML实现略有不同,但是更高级别的概念不同(样式、控制模板、数据模板、内容模型、MVVM、数据绑定)都一样。+1这句话的意思是“忘记java吧。它是一种真正过时的语言,自90年代以来就没有发展过”真的吗?这就是为什么20多个不同的MVVM第三方(大多数开源)图书馆的存在有助于实现这一混乱局面,因为它很容易实现,而且比现有的任何东西都要好得多。我建议你以更诚实的方式展示你的专家知识。你只是在与criticm讨论时忽略了一些与讨论主题毫不相关的有效关注点和问题。你的最后一句话一定是个笑话(我希望如此)。说得够多了。你关于Java vs WPF的一句话基本上只是观点,而基于事实的说法(Java自90年代以来就没有发展)是完全不真实的。我自己也不是Java的粉丝,但你的开场白是离题的,删除它会改进答案。是的,基本上这是一个更“自制”的说法我所描述的版本。我想这是可以接受的,因为WPF和Windows Phone之间的XAML实现不同。Hi@StepTNT如果我键入您的解决方案并亲自尝试,我会得到一个错误:“WPFAApplication18.BaseControl”不能是XAML文件的根,因为它是使用XAML定义的。第1行位置20。我该怎么办是否出错?您应该打开一个新问题并添加一些代码,复制和粘贴并不总是有效:)在Silverlight(即Windows Phone)上,也可能在WinRT上(因此也包括通用应用程序),您可以扩展用户控件,它们应该在Visual Studio designer中工作。据我所见,WPF的情况并非如此。Visual Studio中WPF的XAML设计器尚不支持此功能。有关使用Visual继承的WPF解决方案,请参阅:或有关在祖先中显式定义GUI的信息,请参阅