对ContentPresenter非常困惑

oct*_*ion 4 windows silverlight windows-phone-7

仅供参考我是Silverlight的新手.

好的,所以我想构建一个简单的用户控件,它包含一个按钮以及控件客户端指定的一些额外的XAML.

我在Google上搜索,发现至少30篇不同的文章都非常令人困惑; 特别是因为他们谈论样式动画,定制你不拥有的其他控件,以及其他我尚未做好准备的废话.

这就是我做的.

  • 在VS 2010中,我右键单击并添加了一个名为MyControl的新UserControl
  • 对于MyControl.xaml,我将LayoutRoot更改为StackPanel并在其中添加了一个Button
  • 在我的MainPage.xaml中,我添加了一个MyControl实例
  • 我添加了一个TextBox作为此实例的子元素
  • 我试图构建并得到MyControl不支持直接内容的错误

用Google搜索更多..

  • 我将MyControl改为继承ContentControl并更新了xaml
  • 我在xaml中添加了一个ContentPresenter来表示客户端"自定义内容"

好的,它构建并且TextBox显示,但Button缺失.

这是MainPage.xaml的相关部分

<my:MyControl HorizontalAlignment="Left" Margin="49,26,0,0" x:Name="myContentControl1" VerticalAlignment="Top" Height="550" Width="389">
     <TextBox Height="72" HorizontalAlignment="Left" Margin="166,339,0,0" Name="textBox1" Text="TextBox" VerticalAlignment="Top" Width="460" />
</my:MyControl>
Run Code Online (Sandbox Code Playgroud)

这是MyControl.xaml

<ContentControl x:Class="ContentControlTest.MyControl"
    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">

    <StackPanel x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}" Orientation="Vertical">
        <ContentPresenter/>
        <Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="78,254,0,0" Name="FooFoo" VerticalAlignment="Bottom" Width="160" />
    </StackPanel>
</ContentControl>
Run Code Online (Sandbox Code Playgroud)

这是MyControl.cs

using System.Windows.Controls;

namespace ContentControlTest
{
    public partial class MyControl : ContentControl
    {
        public MyControl()
        {
            InitializeComponent();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为它的工作方式是控件实例的子元素被设置为MyControl的ContentControl基类的Content属性.然后,ContentPresenter将该内容"粘贴"到MyControl.xaml中的任何位置.

虽然这似乎确实如何工作,但在这个过程中它正在"吃掉"我在MyControl.xaml中定义的Button.

我试图不进入ControlTemplate等,除非绝对必要.

有人可以告诉我我做错了什么.

谢谢!

Ale*_*ven 5

那是因为控件的内容是你手工编写的整个StackPanel; 设置新内容时,将替换StackPanel.

我认为,这种情况需要ControlTemplate; 毕竟这将是一个非常简单的.起点可以是内容控件默认样式 ; 将样式放在ResourceDictionary中(例如,在<ContentControl.Resources>用户控件的部分中),您就可以开始了; 您需要做的就是在该模板中添加一个网格和按钮.

请注意,我链接的样式将自身设置为任何可到达的ContentControl的默认值; 使其仅适用于您的控件而不适用于可能出现在其中的任何子项,添加x:Key="someKey"到Style并显式设置ContentControl的Style属性Style={StaticResource someKey}.

如果您需要其他信息,请告诉我们; 另外,我可能错了,可能有一种更简单的方法,但我对此表示怀疑; Content属性的行为与您描述的完全相同.