Winui 3:如何在xaml代码中添加自定义控件到集合属性?



我有两个自定义控件:

  • CustomControl1
public sealed class CustomControl1 : Control
{
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register(
nameof(DetailsList.Items), typeof(ObservableCollection<CustomControl2>), typeof(CustomControl1),
PropertyMetadata.Create(new CreateDefaultValueCallback(() =>
{
return new ObservableCollection<CustomControl2>();
}))

);

public ObservableCollection<CustomControl2> Items
{
get { return (ObservableCollection<CustomControl2>)GetValue(ItemsProperty); }

}

public CustomControl1()
{
SetValue(ItemsProperty, new ObservableCollection<CustomControl2>());
this.DefaultStyleKey = typeof(CustomControl1);

}

}

<Style TargetType="local2:CustomControl1" >

<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local2:CustomControl1">
<ItemsControl ItemsSource="{TemplateBinding Items}"></ItemsControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
  • CustomControl2
public sealed class CustomControl2 : Control
{
public CustomControl2()
{
this.DefaultStyleKey = typeof(CustomControl2);
}
}
<Style TargetType="local2:CustomControl2" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local2:CustomControl2">
<Border
Height="30"
Background="Red"
BorderBrush="Black"
BorderThickness="1">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

我想添加一些CustomControl2项到CustomControl1。项目

<myControls:CustomControl1>
<myControls:CustomControl1.Items>
<myControls:CustomControl2></myControls:CustomControl2>
<myControls:CustomControl2></myControls:CustomControl2>
<myControls:CustomControl2></myControls:CustomControl2>

</myControls:CustomControl1.Items>
</myControls:CustomControl1>

当我编译代码工作时,但当我在调试模式下添加新项目时,给我一个错误:

错误XHR0015 CustomControl2无法添加到ObservableCollection ' 1。

我在代码中做错了什么?正确的做法是什么?

恕我直言,在你的代码中有几行我不理解。例如,您实现Items的方式依赖属性和值detailist.

所以,既然我不能重现你的问题,我就分享一个适合我的示例代码。当点击按钮时,它将添加一个新的CustomControl2Items

Generic.xaml

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinUI3App2">
<Style TargetType="local:CustomControl1">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CustomControl1">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel>
<Button x:Name="ButtonControl" />
<ItemsControl ItemsSource="{TemplateBinding Items}" />
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:CustomControl2">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CustomControl2">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBlock Text="{TemplateBinding Name}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

CustomControl1.cs

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Collections.ObjectModel;
namespace WinUI3App2;
[TemplatePart(Name = nameof(ButtonControl), Type = typeof(Button))]
public sealed class CustomControl1 : Control
{
public CustomControl1()
{
this.DefaultStyleKey = typeof(CustomControl1);
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (this.ButtonControl is not null)
{
this.ButtonControl.Click -= ButtonControl_Click;
}
if (GetTemplateChild(nameof(this.ButtonControl)) is Button button)
{
this.ButtonControl = button;
this.ButtonControl.Click += ButtonControl_Click;
}
}
private void ButtonControl_Click(object sender, RoutedEventArgs e)
{
this.Items.Add(new CustomControl2() { Name = "New Item" });
}
private Button? ButtonControl { get; set; }
public ObservableCollection<CustomControl2> Items
{
get => (ObservableCollection<CustomControl2>)GetValue(ItemsProperty);
set => SetValue(ItemsProperty, value);
}
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
nameof(Items),
typeof(ObservableCollection<CustomControl2>),
typeof(CustomControl1),
new PropertyMetadata(new ObservableCollection<CustomControl2>()));
}

CustomControl2.cs

using Microsoft.UI.Xaml.Controls;
namespace WinUI3App2;
public sealed class CustomControl2 : Control
{
public CustomControl2()
{
this.DefaultStyleKey = typeof(CustomControl2);
}
}

MainWindow.xaml

<Window
x:Class="WinUI3App2.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:local="using:WinUI3App2"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<local:CustomControl1>
<local:CustomControl1.Items>
<local:CustomControl2 x:Name="CustomControl2A"/>
<local:CustomControl2 x:Name="CustomControl2B"/>
<local:CustomControl2 x:Name="CustomControl2C"/>
</local:CustomControl1.Items>
</local:CustomControl1>
</Grid>
</Window>

最新更新