C# UserControl 中的 ContentPresenter
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11558298/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ContentPresenter in UserControl
提问by krzychu
I'm new to WPF and I'm trying to create an UserControl which will have some nested content.
我是 WPF 的新手,我正在尝试创建一个包含一些嵌套内容的 UserControl。
<my:InformationBox Header="General Information" Width="280">
<StackPanel>
<Label>Label1</Label>
<Label>Label2</Label>
</StackPanel>
</my:InformationBox>
As you can see I want to put a StackPanel into it. As I read some articles I am supposed to add ContentPresenter to my UserControl, so I did, but I cannot find what should be binded to it's Content property.
如您所见,我想将 StackPanel 放入其中。当我阅读一些文章时,我应该将 ContentPresenter 添加到我的 UserControl,所以我做了,但我找不到应该绑定到它的 Content 属性的内容。
Here is my UserControl code
这是我的用户控制代码
<UserControl x:Class="ITMAN.InformationBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="200" d:DesignWidth="280" Name="infoBox" Loaded="infoBox_Loaded">
<StackPanel Width="{Binding ElementName=infoBox, Path=Width}" HorizontalAlignment="Stretch">
<Label Content="{Binding ElementName=infoBox, Path=Header}" />
<Border BorderThickness="0,1,0,0" Padding="10 5" Margin="5 0 5 10" BorderBrush="#B4CEDE">
<StackPanel>
<ContentPresenter Content="{Binding Content}" />
<Label Content="End" />
</StackPanel>
</Border>
</StackPanel>
</UserControl>
I've tried many combinations from various articles, but I cannot find any working example of what I want to achieve.
我尝试了各种文章中的多种组合,但找不到任何我想要实现的工作示例。
Similiar question was asked earlier by another user, but given there answers didn't help me: Does anyone have a simple example of a UserControl with a single ContentPresenter?
另一个用户早些时候提出了类似的问题,但给出的答案对我没有帮助:是否有人有一个简单的 UserControl 示例和单个 ContentPresenter?
采纳答案by krzychu
I solved this problem by applaying custom style to GroupBox. I've created Syle in ResourceDictionary, which looks as follows
我通过将自定义样式应用于GroupBox. 我在 中创建了 Syle ResourceDictionary,它看起来如下
<Style x:Key="InformationBoxStyle" TargetType="GroupBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label>
<ContentPresenter Margin="4" ContentSource="Header"
RecognizesAccessKey="True" />
</Label>
<Border Grid.Row="1" BorderThickness="0,1,0,0" Padding="10 5"
Margin="5 0 5 10" BorderBrush="#B4CEDE">
<StackPanel>
<ContentPresenter />
</StackPanel>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And applied this style to GroupBox
并将这种风格应用于 GroupBox
<GroupBox Header="General Information" Width="280" Style="{StaticResource InformationBoxStyle}">
<StackPanel>
<Label>Label1</Label>
<Label>Label2</Label>
</StackPanel>
</GroupBox>
This code works as expected
此代码按预期工作
You may also refer to this great article, which shows different options to achieve it:
http://www.codeproject.com/Articles/82464/How-to-Embed-Arbitrary-Content-in-a-WPF-ControlIt also describes why ContentPresenterdoesn't work in my code.
您也可以参考这篇很棒的文章,其中显示了实现它的不同选项:http:
//www.codeproject.com/Articles/82464/How-to-Embed-Arbitrary-Content-in-a-WPF-Control它也描述了为什么ContentPresenter在我的代码中不起作用。
回答by dowhilefor
ContentPresenteris kind of a magic control. If you don't supply anything to it, it will automatically set the Content, ContentTemplateand ContentTemplateSelectorproperty with a TemplateBindingto the TemplatedParent. Which means, you don't need to supply anything to it, just
ContentPresenter是一种魔法控制。如果您不向它提供任何内容,它会自动将Content,ContentTemplate和ContentTemplateSelector属性设置TemplateBinding为 TemplatedParent。这意味着,你不需要向它提供任何东西,只要
<ContentPresenter/>
in your UserControl, and it should automatically use the corresponding properties found in your UserControl.
Also remember that a binding like {Binding Content}always referes to your DataContext, which i guess is not what you wanted.
在您的 UserControl 中,它应该自动使用在您的 UserControl 中找到的相应属性。还请记住,像这样的绑定{Binding Content}总是指您的 DataContext,我想这不是您想要的。
回答by Michael Puckett II
You need to create a dependency property on your UserControl code behind such as InnerContent.
您需要在后面的 UserControl 代码上创建一个依赖属性,例如 InnerContent。
public object InnerContent
{
get { return GetValue(InnerContentProperty); }
set { SetValue(InnerContentProperty, value); }
}
public static readonly DependencyProperty InnerContentProperty =
DependencyProperty.Register("InnerContent", typeof(object), typeof(ConfirmationControl), new PropertyMetadata(null));
Then you need to bind to that InnerContent on the XAML side of that UserControl.
然后,您需要绑定到该 UserControl 的 XAML 端的该 InnerContent。
<ContentControl Content="{Binding InnerContent, ElementName=userControl}" />
Then when you use it instead of placing content in the UserControl directly and overwriting the existing content just add it to the InnerContent portion.
然后,当您使用它而不是将内容直接放在 UserControl 中并覆盖现有内容时,只需将其添加到 InnerContent 部分即可。
<UserControls:InformationBox>
<UserControls:InformationBox.InnerContent>
<TextBlock Text="I'm in the InnerContent" />
</UserControls:InformationBox.InnerContent>
</UserControls:InformationBox>
Otherwise using a Template or Style is just as good but if you're wanting to package up a UserControl for use without forcing anyone to also reference a style or template this is probably one of your better options.
否则,使用模板或样式也一样好,但如果您想打包一个 UserControl 以供使用,而不强迫任何人也引用样式或模板,这可能是您更好的选择之一。

