如何创建包含占位符以供以后使用的WPF用户控件

dbf7pr2w  于 2022-12-30  发布在  其他
关注(0)|答案(2)|浏览(123)

我最好用例子来问这个问题。假设我有UserControl和使用这个控件的Window。
我想这样设计这个控件(名为MyControl)(这是科幻语法!):

<Grid>
  <Button>Just a button</Button>
  <PlaceHolder Name="place_holder/>
</Grid>

并在设计我的Windows时以这样的方式使用:

<MyControl/>

<MyControl>
  <place_holder>
    <Button>Button 1</Button>
  </place_holder>
</MyControl>

<MyControl>
  <place_holder>
    <Button>Button 1</Button>
    <Button>Button 2</Button>
  </place_holder>
</MyControl>

当然,我希望能够在Windows中向MyControl添加更多的元素。因此,在某种程度上,它应该作为容器工作(如Grid、StackPanel等)。位置将在UserControl中定义(在本例中,在按钮“Just a button”之后),但添加什么(哪些元素)将在Windows中定义(其中使用UserControl -- MyControl --)。

  • 我希望这是我想要达到的目标。关键是在设计窗口时使用XAML,所以我的类应该不会比其他控件差。*

现在,最大的问题是--如何做到这一点?
备注:样式超出范围。我所要做的只是在设计Window时(而不是在设计MyControl时)向MyControl添加任何所需的控件。

shyt4zoc

shyt4zoc1#

ContentControls和ItemsControls非常适合于此,您可以将它们绑定到UserControl的属性或公开它们。
使用ContentControl(用于多个断开位置中的占位符):

<UserControl x:Class="Test.UserControls.MyUserControl2"
             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" 
             Name="control">
    <Grid>
        <Button>Just a button</Button>
        <ContentControl Content="{Binding PlaceHolder1, ElementName=control}"/>
    </Grid>
</UserControl>
public partial class MyUserControl2 : UserControl
{
    public static readonly DependencyProperty PlaceHolder1Property =
        DependencyProperty.Register("PlaceHolder1", typeof(object), typeof(MyUserControl2), new UIPropertyMetadata(null));
    public object PlaceHolder1
    {
        get { return (object)GetValue(PlaceHolder1Property); }
        set { SetValue(PlaceHolder1Property, value); }
    }

    public MyUserControl2()
    {
        InitializeComponent();
    }
}
<uc:MyUserControl2>
    <uc:MyUserControl2.PlaceHolder1>
        <TextBlock Text="Test"/>
    </uc:MyUserControl2.PlaceHolder1>
</uc:MyUserControl2>

ItemsControl-Version(用于一个位置中的集合)
一个一个三个一个一个一个一个一个四个一个一个一个一个一个五个一个
使用UserControls,您可以决定公开内部控件的某些属性;除了ItemsSource之外,你可能还想公开ItemsControl.ItemTemplate这样的属性,但这完全取决于你想如何使用它,如果你只是设置了Items,那么你不一定需要任何这些属性。

o2gm4chl

o2gm4chl2#

我认为您希望在UserControl的ControlTemplate中设置一个ContentPresenter(这样您就可以定义内容将显示在何处)。
您的自定义UserControl:

<UserControl x:Class="TestApp11.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <UserControl.Template>
        <ControlTemplate>
            <StackPanel>
                <TextBlock Text="Custom Control Text Area 1" />
                <ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
                <TextBlock Text="Custom Control Text Area 2" />
            </StackPanel>
        </ControlTemplate>
    </UserControl.Template>
</UserControl>

用法:

<Window x:Class="TestApp11.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:l="clr-namespace:TestApp11"
    Title="Window1" Height="250" Width="200">
    <StackPanel>
        <l:UserControl1>
            <Button Content="My Control's Content" />
        </l:UserControl1>
    </StackPanel>
</Window>

如果你的内容部分需要多个条目,只需将它们放在一个容器中,比如网格或堆栈面板:

<l:UserControl1>
    <StackPanel>
        <Button Content="Button 1" />
        <Button Content="Button 2" />
    </StackPanel>
</l:UserControl1>

相关问题