编辑(如评论:XY问题) - 问题:
我想创建自己的控件,它具有预定义的特殊元素的样式和位置(Button,...),但一般来说,所有内容都应该放在我的自定义控件中。在我的情况下,自定义控件只是一个“菜单栏”,应该能够在“GUI代码”中的任何地方使用 - 但是没有必要在那里。但使用时,它应该是相同的风格和行为。一种风格 - 我认为 - 还不够,因为此菜单栏中还有预定义的元素(例如,帮助已经在菜单栏中)
编辑结束。
我想在WPF中构建一个自定义控件(只是一个特殊的堆栈面板),具有以下要求: 可以用作xaml中的任何其他控件 已为自定义控件
中的控件定义样式首先,我只是尝试创建一个UserControl,其中包含一个带有已定义样式(在xaml中)的stackpanel,用于包含元素(例如Button)。
包含此UserControl<ContentPresenter />
在xaml中。使用此方法,无法命名包含元素。 E.g:
<mynamespace:MyStackPanel>
<Button Name="w00t">This does not work!</Button>
</mynamespace:MyStackPanel>
接下来尝试创建一个“真正的”自定义控件。这个自定义控件只是一个没有xaml的类。代码很简单。类继承自UserControl并且只包含:
StackPanel sp = new StackPanel();
sp.Children.Add(new ContentPresenter());
this.AddChild(sp);
Woooohoooo,现在可以命名包含元素。但仍然是一个大问题:如何定义样式?
我可以在ResourceDictionary中为我自己的自定义控件定义样式。但我必须将ResourceDictionary添加到全局(App.xaml)资源中。然后我只能为我的自定义控件定义样式 - 而不是包含元素? - 但无论如何......这样做只是感觉不对劲!
所以主要的问题是:创建自定义控件的“正确”方法是什么,可以像任何其他控件一样在xaml中使用?如果第二种方式是正确的方法 - 如何设置样式就像我在xaml中那样(例如,这个元素中的每个Button都有一个特殊的样式)并且它是一个“全局”的ResourceDictionary?
如何在第三方内容中实施?
答案 0 :(得分:2)
好的,我为你做了一个例子,涉及Custom Controls
(与UserControl
s相反)
第1步:
创建一个从ContentControl
派生的新类(仅代码,没有XAML)(或任何具有类似于您需要的行为的UI元素)
public class ReusableContainer : ContentControl
{
public static readonly DependencyProperty ButtonProperty = DependencyProperty.Register("Button", typeof(Button), typeof(ReusableContainer), new PropertyMetadata(default(Button)));
public Button Button
{
get { return (Button)GetValue(ButtonProperty); }
set { SetValue(ButtonProperty, value); }
}
}
在这里看看我如何将Button
属性定义为DependencyProperty。您可以为自定义控件中需要的“内容占位符”添加更多DP。
第2步:
在单独的ResourceDictionary
:
CustomStyles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Button">
<Setter Property="Background" Value="Green"/>
</Style>
</ResourceDictionary>
app.xaml
中的 第3步:,为ReusableContainer
定义应用程序范围的样式,该样式定义了它的模板:
<Application x:Class="WpfApplication14.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication14"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="{x:Type local:ReusableContainer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ReusableContainer}">
<ControlTemplate.Resources>
<ResourceDictionary Source="CustomStyles.xaml"/>
</ControlTemplate.Resources>
<ContentPresenter Content="{TemplateBinding Button}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
了解我如何使用TemplateBinding
表达式来定义ContentPresenter
的内容将由Button
中的ReusableContainer
属性定义。< / p>
另请注意我如何将CustomStyles.xaml
中的资源添加到ControlTemplate.Resources
集合中。这使得这些资源可用于模板中的所有UI元素。
第4步:
将ReusableContainer放在窗口中:
<Window x:Class="WpfApplication14.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication14"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<local:ReusableContainer>
<local:ReusableContainer.Button>
<Button x:Name="Button1" Content="Hello! Button 1"/>
</local:ReusableContainer.Button>
</local:ReusableContainer>
<local:ReusableContainer>
<local:ReusableContainer.Button>
<Button x:Name="Button2" Content="Hello! Button 2"/>
</local:ReusableContainer.Button>
</local:ReusableContainer>
<local:ReusableContainer>
<local:ReusableContainer.Button>
<Button x:Name="Button3" Content="Hello! Button 3"/>
</local:ReusableContainer.Button>
</local:ReusableContainer>
</StackPanel>
</Window>