在面向10240的UWP应用中;我知道当您尝试添加已在您收到的UI中绘制的元素时:
元素已经是另一个元素的子元素了。'
但是我在页面的资源中有一个边框,按代码添加它,并收到相同的异常。
<Page
x:Class="App13.MainPage"
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"
mc:Ignorable="d">
<Page.Resources>
<Border Width="100" Height="100" Background="Red" x:Name="Border" x:Key="Border" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Height="100" Width="100" Content="Add" Tapped="Button_Tapped"/>
</Grid>
using Windows.UI.Xaml.Input;
namespace App13
{
public sealed partial class MainPage : Page
{
public MainPage() => InitializeComponent();
private void Button_Tapped(object sender, TappedRoutedEventArgs e)
{
var border = Resources["Border"] as Border;
if (!(Content is Panel panel)) return;
panel.Children.Add(border);
}
}
}
如果元素在资源字典中,但尚未呈现,那么它又如何成为另一个元素的子元素?
答案 0 :(得分:2)
元素已经是另一个元素的子元素了。&#39;
UWP中的每个UI元素一次只能在一个位置的UI中使用。加载资源时将生成实例。因此,您无法再将它们添加到面板中。但是,您可以通过关注UIElementExtensions
创建深层副本,然后将副本添加到面板中。
public static class UIElementExtensions
{
public static T DeepClone<T>(this T source) where T : UIElement
{
T result;
// Get the type
Type type = source.GetType();
// Create an instance
result = Activator.CreateInstance(type) as T;
CopyProperties<T>(source, result, type);
DeepCopyChildren<T>(source, result);
return result;
}
private static void DeepCopyChildren<T>(T source, T result) where T : UIElement
{
// Deep copy children.
Panel sourcePanel = source as Panel;
if (sourcePanel != null)
{
Panel resultPanel = result as Panel;
if (resultPanel != null)
{
foreach (UIElement child in sourcePanel.Children)
{
// RECURSION!
UIElement childClone = DeepClone(child);
resultPanel.Children.Add(childClone);
}
}
}
}
private static void CopyProperties<T>(T source, T result, Type type) where T : UIElement
{
// Copy all properties.
IEnumerable<PropertyInfo> properties = type.GetRuntimeProperties();
foreach (var property in properties)
{
if (property.Name != "Name")
{
if ((property.CanWrite) && (property.CanRead))
{
object sourceProperty = property.GetValue(source);
UIElement element = sourceProperty as UIElement;
if (element != null)
{
UIElement propertyClone = element.DeepClone();
property.SetValue(result, propertyClone);
}
else
{
try
{
property.SetValue(result, sourceProperty);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
}
}
}
}
}
}
<强>用法强>
private void Button_Tapped(object sender, TappedRoutedEventArgs e)
{
var border = Resources["Border"] as Border;
if (!(Content is Panel panel)) return;
var NewBorder = border.DeepClone<Border>();
panel.Children.Add(NewBorder);
}