我尝试创建一个“容器”用户控件,可以在WPF中将UIElement
个对象显示为子对象。控件的用法应如下所示:
<general:DisplayContainer Title="Hello">
<TextBlock x:Name="AnyUIElement" />
</general:DisplayContainer>
其中TextBlock只是一个例子。到目前为止,我创建了UserControl并绑定了Title属性,如下所示:
<Grid x:Name="Grid_Main">
<Border x:Name="Border_Main" BorderThickness="2" Margin="10" CornerRadius="5" Padding="7" />
<TextBlock x:Name="TextBlock_Title" Background="{Binding Background, ElementName=Grid_Main}" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Path=Title, FallbackValue=Title}" Margin="20,2,0,0" Padding="3,0" />
</Grid>
Codebehind文件如下所示:
public partial class DisplayContainer : UserControl
{
public DisplayContainer()
{
InitializeComponent();
this.DataContext = this;
}
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title",typeof(string), typeof(DisplayContainer));
}
现在,我如何以某种方式修改我的控件,当我使用控件时,我接受XAML文件中的子元素?应通过Border_Main.Child
属性显示孩子。
提前致谢,
弗兰克
答案 0 :(得分:1)
只需设置UserControl的模板属性
即可// obtain a validator
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
// do a test
Set<ConstraintViolation<User>> constraintViolations = validator.validate(user2);
Assert.assertEquals(0, constraintViolations.size());
并将显示的元素放在UserControl的内容中:
<UserControl ...>
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<StackPanel>
<TextBlock Text="{Binding Title,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
<ContentPresenter />
</StackPanel>
</ControlTemplate>
</UserControl.Template>
</UserControl>
答案 1 :(得分:1)
或者您可以将DisplayContainer
定义为ContentControl
,而不是.xaml
文件但ControlTemplate
:
public partial class DisplayContainer : ContentControl
{
public DisplayContainer()
{
this.DataContext = this;
}
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(DisplayContainer));
}
<强> XAML:强>
<Window x:Class="WpfApp1.MainWindow"
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"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300">
<Window.Resources>
<Style TargetType="local:DisplayContainer">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:DisplayContainer">
<Grid x:Name="Grid_Main">
<Border x:Name="Border_Main" BorderThickness="2" Margin="10" CornerRadius="5" Padding="7">
<ContentPresenter />
</Border>
<TextBlock x:Name="TextBlock_Title" Background="{Binding Background, ElementName=Grid_Main}"
HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding Path=Title, RelativeSource={RelativeSource AncestorType=local:DisplayContainer}, FallbackValue=Title}" Margin="20,2,0,0" Padding="3,0" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<local:DisplayContainer Title="Hello">
<TextBlock Text="AnyUIElement..." />
</local:DisplayContainer>
</StackPanel>
</Window>
答案 2 :(得分:0)
或者,换句话说。
如果您需要不同的部分,可以添加许多DP。只需添加更多绑定到不同DP(Content,Header,Footer等)的ContentPresenters。
DisplayContainer.cs
[System.Windows.Markup.ContentProperty("Child")]
public partial class DisplayContainer : UserControl
{
public DisplayContainer()
{
InitializeComponent();
}
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(DisplayContainer));
public UIElement Child
{
get { return (UIElement)GetValue(ChildProperty); }
set { SetValue(ChildProperty, value); }
}
public static readonly DependencyProperty ChildProperty = DependencyProperty.Register("Child", typeof(UIElement), typeof(DisplayContainer));
}
DisplayContainer.xaml
<UserControl x:Class="WpfApp19.DisplayContainer"
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"
xmlns:local="clr-namespace:WpfApp19"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="Grid_Main">
<Border x:Name="Border_Main" BorderThickness="2" Margin="10" CornerRadius="5" Padding="7">
<ContentPresenter Content="{Binding Child, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</Border>
<TextBlock x:Name="TextBlock_Title" Background="{Binding Background, ElementName=Grid_Main}" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Path=Title, FallbackValue=Title, RelativeSource={RelativeSource AncestorType=UserControl}}" Margin="20,2,0,0" Padding="3,0" />
</Grid>
</UserControl>
MainWindow.xaml
<Window x:Class="WpfApp19.MainWindow"
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"
xmlns:general="clr-namespace:WpfApp19"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<general:DisplayContainer Title="Hello">
<StackPanel>
<TextBlock Text="Test1" />
<TextBlock Text="Test2" />
</StackPanel>
<!-- Alternative way of setting Child - if you had more DPs (Header, Footer, etc..) you would have to set their content this way
<general:DisplayContainer.Child>
<TextBlock Text="AnyUIElement" />
</general:DisplayContainer.Child>
-->
</general:DisplayContainer>
</Grid>
</Window>