Wpf 属性中的自定义控件?

Wpf 属性中的自定义控件?,wpf,Wpf,是否可以创建自定义控件、定义其样式等,然后在使用该控件时将其他控件添加到其属性中。很难解释,所以这里有一些示例代码,显然不起作用,只是为了让您了解我正在尝试做什么: <Controls:TitleContainer> <!-- Title Bar --> <Controls:TitleContainer.Title> <TextBlock>i Information&l

是否可以创建自定义控件、定义其样式等,然后在使用该控件时将其他控件添加到其属性中。很难解释,所以这里有一些示例代码,显然不起作用,只是为了让您了解我正在尝试做什么:

<Controls:TitleContainer>
            <!-- Title Bar -->
            <Controls:TitleContainer.Title>
                <TextBlock>i Information</TextBlock>
            </Controls:TitleContainer.Title>
            <Controls:TitleContainer.Sub>
                <Button Style="{StaticResource BtnSmBlue}" Content="Search" />
            </Controls:TitleContainer.Sub>

            <!-- Main Content -->
            <StackPanel>
                <TextBlock Text="any text here... blah blah" />
                <Button Content="Buttons" />
            </StackPanel>
        </Controls:TitleContainer>

i信息
我想制作一个如下所示的控件,这个容器有一个标题,有些在标题的右边有一个额外的按钮,然后是内容

最好的方法是什么


正如@gomi42所建议的那样,我很想测试这个控件,这里有一个非常简单的示例,您在最后不会以这种方式使用它,但您可以从它开始,稍后添加绑定

<Window.Resources>
    <DataTemplate x:Key="HeaderTemplate1">
        <Grid Background="DarkGray">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto" MinWidth="150"/>
            </Grid.ColumnDefinitions>
            <Border Width="30" Height="30" Background="AliceBlue" Grid.Column="0"></Border>
            <TextBlock Text="SomeHeader" Foreground=" White" Grid.Column="1"></TextBlock>
            <ComboBox Grid.Column="2" SelectedIndex="0" Foreground="Green">
                <ComboBoxItem>item1</ComboBoxItem>
                <ComboBoxItem>item2</ComboBoxItem>
                <ComboBoxItem>item3</ComboBoxItem>
            </ComboBox>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="HeaderTemplate2">
        <Grid Background="DarkGray">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto" MinWidth="300"/>
            </Grid.ColumnDefinitions>
            <Border Width="30" Height="30" Background="AliceBlue" Grid.Column="0"/>
            <TextBlock Text="SomeHeader" Foreground=" White" Grid.Column="1"/>
            <TextBox Grid.Column="2" Background="Green" Foreground="White" Text="Asd"/>
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="ButtonTemplate">
        <StackPanel Orientation="Horizontal">
            <Border Width="30" Height="30" Background="AliceBlue"/>
            <TextBlock Background="Red" Text="Some Button"/>
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="ContentTemplate1">
        <StackPanel Orientation="Vertical" Background="Purple">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="3*" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="Prop1" Foreground="White"/>
                <ProgressBar Grid.Column="1" Height="10" Value="35" Background="Purple" Foreground="GreenYellow" IsIndeterminate="False" Minimum="0" Maximum="100"/>
            </Grid>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="3*" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="Prop2" Foreground="White"/>
                <ProgressBar Grid.Column="1" Height="10" Value="75" Background="Purple" Foreground="GreenYellow" IsIndeterminate="False" Minimum="0" Maximum="100"/>
            </Grid>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="3*" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="Prop3" Foreground="White"/>
                <ProgressBar Grid.Column="1" Height="10" Value="15" Background="Purple" Foreground="GreenYellow" IsIndeterminate="False" Minimum="0" Maximum="100"/>
            </Grid>
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="ContentTemplate2">
        <StackPanel Orientation="Horizontal" Background="Purple">
            <Button Background="Green" Margin="10" ContentTemplate="{StaticResource ButtonTemplate}"/>
            <Button Background="Green" Margin="10" ContentTemplate="{StaticResource ButtonTemplate}"/>
            <Button Background="Green" Margin="10" ContentTemplate="{StaticResource ButtonTemplate}"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<Grid Background="Gray">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <HeaderedContentControl HeaderTemplate="{StaticResource HeaderTemplate1}" 
                            ContentTemplate="{StaticResource ContentTemplate1}"
                            Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Margin="10"/>
    <HeaderedContentControl HeaderTemplate="{StaticResource HeaderTemplate1}" 
                            ContentTemplate="{StaticResource ContentTemplate1}"
                            Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="0" Margin="10"/>
    <HeaderedContentControl HeaderTemplate="{StaticResource HeaderTemplate2}" 
                            ContentTemplate="{StaticResource ContentTemplate2}"
                            Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Margin="10"/>
</Grid>
我们在Xaml中使用相同的控件,但这次我们使用自定义控件

...
<local:CustomControl1 HeaderTemplate="{StaticResource HeaderTemplate1}" 
                            ContentTemplate="{StaticResource ContentTemplate1}"
                            Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Margin="10"/>
    <local:CustomControl1 HeaderTemplate="{StaticResource HeaderTemplate1}" 
                            ContentTemplate="{StaticResource ContentTemplate1}"
                            Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="0" Margin="10"/>
    <local:CustomControl1 HeaderTemplate="{StaticResource HeaderTemplate2}"
                            ContentTemplate="{StaticResource ContentTemplate2}"
                            Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Margin="10"/>
...
<DataTemplate x:Key="ContentTemplate2">
        <StackPanel Orientation="Horizontal" 
                    Background="{Binding Background, RelativeSource={RelativeSource AncestorType=HeaderedContentControl}}">
            <Button Background="Green" Margin="10" ContentTemplate="{StaticResource ButtonTemplate}"/>
            <Button Background="Green" Margin="10" ContentTemplate="{StaticResource ButtonTemplate}"/>
            <Button Background="Green" Margin="10" ContentTemplate="{StaticResource ButtonTemplate}"/>
        </StackPanel>
    </DataTemplate>
。。。
...
只有这一次使用了不同的ContentTemplate2——注意它的后台绑定,它现在从其父级(我们的自定义控件)获取后台属性



只是一个想法:你看了HeaderedContentControl了吗?主要问题是我不想在WindowResources中硬编码标题文本ect,我希望使用模板,然后在控件定义中更改标题文本。如果给控件提供数据上下文,你可以这样做,您可以将所需的文本字段绑定到上下文中的某个值,然后使用本地化转换器(我在项目中使用过这种转换器)。在视图模型中提供一些资源键并绑定到它,然后从转换器中的资源中获取实际值。我已经完成了一次编辑,使用自定义控件中的背景集,并在
数据模板中进行绑定,你也可以检查一下:这是一个关于其他问题的答案,它不是100%适用于你,但它可能会给你一个想法。(在WinRT项目中使用)谢谢,我可能会在某种程度上使用这个
HeaderedContentControl
。Np,这个想法是@gomi42的功劳,这个控件有潜力。至于本地化,使用简单的转换器非常容易,而且它节省了大量时间,您只需绑定到资源键而不是实际值,并且在我看来,视图模型中的代码更加清晰。
<DataTemplate x:Key="ContentTemplate2">
        <StackPanel Orientation="Horizontal" 
                    Background="{Binding Background, RelativeSource={RelativeSource AncestorType=HeaderedContentControl}}">
            <Button Background="Green" Margin="10" ContentTemplate="{StaticResource ButtonTemplate}"/>
            <Button Background="Green" Margin="10" ContentTemplate="{StaticResource ButtonTemplate}"/>
            <Button Background="Green" Margin="10" ContentTemplate="{StaticResource ButtonTemplate}"/>
        </StackPanel>
    </DataTemplate>