Xaml WPF中的TextDecorationCollection序列化
是否有任何xaml序列化属性可以为实际为集合(TextDecorationCollection)的依赖项属性指定 我想使用序列化来克隆一个非常大和复杂的对象。下面是简化的代码示例: 有一个MyVisualObject,它包含许多属性,包括我想要克隆的自定义字体Xaml WPF中的TextDecorationCollection序列化,xaml,serialization,xaml-serialization,Xaml,Serialization,Xaml Serialization,是否有任何xaml序列化属性可以为实际为集合(TextDecorationCollection)的依赖项属性指定 我想使用序列化来克隆一个非常大和复杂的对象。下面是简化的代码示例: 有一个MyVisualObject,它包含许多属性,包括我想要克隆的自定义字体 [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public class Export : Attribute { } public class My
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class Export : Attribute
{
}
public class MyVisualObject : DependencyObject
{
[Export]
public CustomFont Font
{
get { return (CustomFont)GetValue(FontProperty); }
set { SetValue(FontProperty, value); }
}
// Using a DependencyProperty as the backing store for Font. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FontProperty =
DependencyProperty.Register("Font", typeof(CustomFont), typeof(MyVisualObject));
public MyVisualObject()
{
this.Font = new CustomFont();
}
}
自定义字体的定义如下:
public class CustomFont : DependencyObject
{
public TextDecorationCollection Decorations
{
get { return (TextDecorationCollection)GetValue(DecorationsProperty); }
set { SetValue(DecorationsProperty, value); }
}
// Using a DependencyProperty as the backing store for TextDecorations. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DecorationsProperty =
DependencyProperty.Register("Decorations", typeof(TextDecorationCollection), typeof(CustomFont), new UIPropertyMetadata(new TextDecorationCollection()));
public CustomFont()
{
this.Decorations = System.Windows.TextDecorations.Underline;
}
}
<CustomFont xmlns="clr-namespace:WpfApplication1;assembly=WpfApplication1" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<CustomFont.Decorations>
<av:TextDecorationCollection>
<av:TextDecoration Location="Underline" />
</av:TextDecorationCollection>
</CustomFont.Decorations>
</CustomFont>
深度克隆方法:
public static T DeepClone<T>(T from)
{
object clone = Activator.CreateInstance(from.GetType());
Type t = from.GetType();
System.Reflection.PropertyInfo[] pinf = t.GetProperties();
foreach (PropertyInfo p in pinf)
{
bool serialize = false;
foreach (object temp in p.GetCustomAttributes(true))
{
if (temp is Export)
{
serialize = true;
}
}
if (serialize)
{
string xaml = XamlWriter.Save(p.GetValue(from, null));
XmlReader rd = XmlReader.Create(new StringReader(xaml));
p.SetValue(clone, XamlReader.Load(rd), null);
}
}
return (T)clone;
}
克隆过程因以下错误而崩溃:'Add value to collection of type'System.Windows.TextDecorationCollection'引发异常。'行号'1'和行位置'213'
据我所知,序列化就是这一部分
string xaml = XamlWriter.Save(p.GetValue(from, null));
返回未将装饰设置为集合的xaml:
<CustomFont xmlns="clr-namespace:WpfApplication1;assembly=WpfApplication1" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<CustomFont.Decorations>
<av:TextDecoration Location="Underline" />
</CustomFont.Decorations>
</CustomFont>
但是,如果xaml是这样的,克隆过程将起作用:
public class CustomFont : DependencyObject
{
public TextDecorationCollection Decorations
{
get { return (TextDecorationCollection)GetValue(DecorationsProperty); }
set { SetValue(DecorationsProperty, value); }
}
// Using a DependencyProperty as the backing store for TextDecorations. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DecorationsProperty =
DependencyProperty.Register("Decorations", typeof(TextDecorationCollection), typeof(CustomFont), new UIPropertyMetadata(new TextDecorationCollection()));
public CustomFont()
{
this.Decorations = System.Windows.TextDecorations.Underline;
}
}
<CustomFont xmlns="clr-namespace:WpfApplication1;assembly=WpfApplication1" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<CustomFont.Decorations>
<av:TextDecorationCollection>
<av:TextDecoration Location="Underline" />
</av:TextDecorationCollection>
</CustomFont.Decorations>
</CustomFont>
我找到了一个解决方法,可以替换字符串:
xaml = xaml.Replace("<CustomFont.Decorations><av:TextDecoration Location=\"Underline\" /></CustomFont.Decorations>", "<CustomFont.Decorations><av:TextDecorationCollection><av:TextDecoration Location=\"Underline\" /></av:TextDecorationCollection></CustomFont.Decorations>");
xaml=xaml.Replace(“,”);
但是我认为它真的很脏,如果您能提供一个更干净的解决方案(例如为装饰属性指定一个属性),我会非常感激它。您是否尝试将以下属性应用于装饰属性:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]