[英]Unable to set Name property of child controls on UserControl
I created a UserControl .我创建了一个UserControl 。 It contains several elements of specific style and have a DockPanel to contain children which added later on MainWindow.xaml .
它包含几个特定样式的元素,并有一个DockPanel来包含后来添加到MainWindow.xaml上的子项。 It works properly and can have it's children on MainWindow.xaml .
它工作正常,可以在MainWindow.xaml上拥有它的孩子。 But when you set Name property on the any of children, It produces 'the name is aleady used' exception on compiling.
但是,当您在任何子项上设置Name属性时,它会在编译时产生“名称已使用”异常。 What do I have to think more about?
我还需要考虑什么? Without setting Name property, it works properly.
如果不设置Name属性,它可以正常工作。
Exception: Cannot set Name attribute value 'ThisProduceAnError' on element 'TextBlock'.
例外:无法在元素“TextBlock”上设置名称属性值“ThisProduceAnError”。 'TextBlock' is under the scope of element 'PropertyPanel', which already had a name registered when it was defined in another scope.
“TextBlock”位于元素“PropertyPanel”的 scope 下,该名称在另一个 scope 中定义时已经注册了名称。
UserControl.xaml UserControl.xaml
<UserControl x:Class="TrainingWpf1.PropertyPanel"
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:TrainingWpf1"
mc:Ignorable="d"
d:DesignHeight="120" d:DesignWidth="260">
<DockPanel>
<TextBlock DockPanel.Dock="Top" Text="Title"/>
<Border Padding="10" BorderThickness="1" CornerRadius="6" Background="CadetBlue">
<DockPanel x:Name="panContent" />
</Border>
</DockPanel>
</UserControl>
UserControl.xaml.cs UserControl.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
namespace TrainingWpf1
{
[ContentProperty(nameof(Children))]
public partial class PropertyPanel : UserControl
{
public PropertyPanel()
{
InitializeComponent();
this.Children = panContent.Children;
}
public UIElementCollection Children
{
get => (UIElementCollection)GetValue(ChildrenProperty.DependencyProperty);
private set => SetValue(ChildrenProperty, value);
}
public static readonly DependencyPropertyKey ChildrenProperty = DependencyProperty.RegisterReadOnly(
nameof(Children),
typeof(UIElementCollection),
typeof(PropertyPanel),
new PropertyMetadata());
}
}
MainWindow.xaml主窗口.xaml
<Window x:Class="TrainingWpf1.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:TrainingWpf1"
mc:Ignorable="d"
Title="MainWindow" Height="400" Width="400">
<Grid>
<local:PropertyPanel>
<TextBlock Name="ThisProduceAnError" Text="Hello"/>
</local:PropertyPanel>
</Grid>
</Window>
Do not use XAML:不要使用 XAML:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
namespace TrainingWpf1
{
[ContentProperty(nameof(Children))]
public partial class PropertyPanel : UserControl
{
public PropertyPanel()
{
//InitializeComponent();
DockPanel panContent = new DockPanel();
this.Children = panContent.Children;
Border border = new Border()
{
Padding = new Thickness(10),
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(6),
Background = Brushes.CadetBlue,
Child = panContent
};
DockPanel dockPanel = new DockPanel();
TextBlock textBlock = new TextBlock() { Text = "Title" };
textBlock.SetValue(DockPanel.DockProperty, Dock.Top);
dockPanel.Children.Add(textBlock);
dockPanel.Children.Add(border);
Content = dockPanel;
}
public UIElementCollection Children
{
get => (UIElementCollection)GetValue(ChildrenProperty.DependencyProperty);
private set => SetValue(ChildrenProperty, value);
}
public static readonly DependencyPropertyKey ChildrenProperty = DependencyProperty.RegisterReadOnly(
nameof(Children),
typeof(UIElementCollection),
typeof(PropertyPanel),
new PropertyMetadata());
}
}
I made the mistake I wrote about above.我犯了我上面写的错误。 I installed the template in XAML created by Studio.
我将模板安装在 Studio 创建的 XAML 中。 When you add a user control, it creates code from two files: XAML and a partial class in Code-Benind.
添加用户控件时,它会从两个文件创建代码:XAML 和 Code-Benind 中的部分 class。
For default elements, the implementation is different.对于默认元素,实现是不同的。 A separate class in C # with properties and a separate XAML theme with a template for this class.
C 中的一个单独的 class # 带有属性和一个单独的 XAML 主题,带有此 ZA2F2ED4F8EBC04AB614C21A29DDC 的模板See how custom elements are implemented.
查看自定义元素是如何实现的。
Having done this, I got a working code.完成此操作后,我得到了一个工作代码。 To simplify the example, I did not set a theme, but created a default style in the window resources.
为了简化示例,我没有设置主题,而是在 window 资源中创建了默认样式。
C# for UserControl C# 用于用户控制
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
namespace TrainingWpf1
{
[ContentProperty(nameof(Children))]
public class PropertyPanel : UserControl
{
public PropertyPanel()
{
Children = new ObservableCollection<UIElement>();
}
public ObservableCollection<UIElement> Children
{
get => (ObservableCollection<UIElement>)GetValue(ChildrenProperty.DependencyProperty);
private set => SetValue(ChildrenProperty, value);
}
public static readonly DependencyPropertyKey ChildrenProperty = DependencyProperty.RegisterReadOnly(
nameof(Children),
typeof(ObservableCollection<UIElement>),
typeof(PropertyPanel),
new PropertyMetadata(null));
}
}
XAML for Window XAML 用于 Window
<Window x:Class="TrainingWpf1.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:TrainingWpf1"
mc:Ignorable="d"
Title="MainWindow" Height="400" Width="400"
>
<Window.Resources>
<Style TargetType="{x:Type local:PropertyPanel}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<DockPanel>
<TextBlock DockPanel.Dock="Top" Text="Title"/>
<Border Padding="10" BorderThickness="1" CornerRadius="6" Background="CadetBlue">
<ItemsControl ItemsSource="{Binding Children, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PropertyPanel}}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<local:PropertyPanel>
<TextBlock x:Name="ThisProduceAnError" Text="Hello"/>
</local:PropertyPanel>
</Grid>
</Window>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.