如何解决序列化自定义层次结构集合时出现问题
| 我必须填充一个已为其进行自定义集合的树视图 这是自定义集合的类public class EntityBase : ObservableCollection<object>
{
private string name;
public string Name
{
get { return name; }
set
{
name = value;
InvokePropertyChange(this,new PropertyChangedEventArgs(\"Name\"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void InvokePropertyChange(object sender,PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(sender,e);
}
}
}
public class ParentX : EntityBase // Should be the root of my XML
{
}
public class Parent : EntityBase
{
private ChildC _childC;
public ChildC ChildC
{
get { return _childC; }
set { _childC = value; }
}
}
public class ChildA : EntityBase
{
}
public class ChildB : EntityBase
{
}
public class ChildC : EntityBase
{
private ObservableCollection<ChildB> children = new ObservableCollection<ChildB>();
public ObservableCollection<ChildB> Children
{
get { return children; }
set { children = value; }
}
}
这是我按层次结构顺序填充数据的方式,以便可以填充异构树...
public class DataBase
{
public ObservableCollection<object> GetData()
{
ChildB childB1 = new ChildB { Name = \"Parent 1 - ChildB 1\" };
ChildB childB2 = new ChildB { Name = \"Parent 1 - ChildB 2\" };
ChildA childA1 = new ChildA { childB1,childB2 }; // ChildA will have ChildB objects as its child
childA1.Name = \"Parent 1 - ChildA 1\";
ChildC childC = new ChildC{Name=\"CHildC\"};
for (int i = 0; i < 5; i++)
{
childC.Children.Add(new ChildB{Name=\"Pappu\" + i}); // childC children Property will have childB Object
}
Parent parent1 = new Parent {childC,childA1}; // Parent class will have ChildC and ChildA as its child
parent1.Name = \"Parent1\";
//Family 2
ParentX parentX=new ParentX{Name=\"Parent\"};
parentX.Add(parent1); //ParentX will have Parent as its child
return new ObservableCollection<object> { parentX };
}
}
这是我正在使用的序列化代码.....
using (FileStream fileStream=new FileStream(@\"D:\\text.xml\",FileMode.Create))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(ParentX),new Type[] { typeof(Parent),typeof(ChildA),typeof(ChildC),typeof(ChildB)});
if (data != null) xmlSerializer.Serialize(fileStream,data);
}
我被困在这个.....它不序列化给出了错误....
{\"There was an error generating the XML document.\"}
\"The type HierarchialTreeView.Model.ChildC may not be used in this context.\"
请帮我解决这个问题
填充所需类型的异构树视图很困难,现在发生了这种情况
谢谢Ne的方式...社区非常有帮助:)
编辑:
内部异常:
{\“在此上下文中,不能使用类型HierarchialTreeView.Model.ChildC。\”}
内在异常= null
此后没有更多例外了。。。。
堆栈跟踪(如果有人需要):
System.InvalidOperationException was unhandled
Message=There was an error generating the XML document.
Source=System.Xml
StackTrace:
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter,Object o,XmlSerializerNamespaces namespaces,String encodingStyle,String id)
at System.Xml.Serialization.XmlSerializer.Serialize(Stream stream,XmlSerializerNamespaces namespaces)
at System.Xml.Serialization.XmlSerializer.Serialize(Stream stream,Object o)
at HierarchialTreeView.MainWindow.Button_Click(Object sender,RoutedEventArgs e)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target,RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source,RoutedEventArgs args,Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender,RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.Primitives.ButtonBase.OnClick()
at System.Windows.Controls.Button.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender,MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler,Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler,Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target,Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender,RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseUpThunk(Object sender,RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args,Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd,InputMode mode,Int32 timestamp,RawMouseActions actions,Int32 x,Int32 y,Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd,WindowMessage msg,IntPtr wParam,IntPtr lParam,Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd,Int32 msg,Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd,Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback,Object args,Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source,Delegate method,Int32 numArgs,Delegate catchHandler)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority,TimeSpan timeout,Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd,IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at HierarchialTreeView.App.Main()
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly,String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.InvalidOperationException
Message=The type HierarchialTreeView.Model.ChildC may not be used in this context.
Source=System.Xml
StackTrace:
at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name,String ns,Boolean xsiType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterParentX.Write1_Object(String n,Boolean isNullable,Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterParentX.Write1_Object(String n,Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterParentX.Write2_ArrayOfAnyType(Object o)
InnerException:
解决方法
这是可以序列化的父/子节点层次结构的示例。请注意,使用了用于ObservableCollections并用作Node基类的公共类Entity。在实体上使用XmlInclude属性来警告序列化程序如何处理作为节点的实体。
还要注意此示例显示XmlInclude在另一个层次结构上的用法。
控制台输出和序列化的XML包括在下面。
using System;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Collections.Specialized;
using System.IO;
using System.Xml.Serialization;
namespace StackoverflowSerializingHierarchy
{
// Use System.Xml.Serialization.XmlInclude attribute to let
// serialize know how to handle an Entity that is a Node
[XmlInclude(typeof(Node))]
public abstract class Entity : INotifyPropertyChanged
{
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this,new PropertyChangedEventArgs(name));
}
}
// Name Property
private string _name;
public string Name
{
get {
return _name;
}
set {
if (value == null)
value = String.Empty;
if (String.IsNullOrEmpty(_name) || !_name.Equals(value)) {
_name = value;
OnPropertyChanged(\"Name\");
}
}
}
}
// use a Node class to represent an Entity that can have children
public class Node : Entity
{
public Node() : base()
{
PropertyChanged += DataBase.DataPropertyChanged;
}
// Children property is an observable collection of the common base class Entity
private ObservableCollection<Entity> _children;
public ObservableCollection<Entity> Children
{
get
{
return this._children;
}
set
{
this._children = value;
if (this._children != null)
{
this._children.CollectionChanged += DataBase.DataCollectionChanged;
}
}
}
}
class Util
{
public static void SerializeObjectToXML<T>(T item,string FilePath)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
using (StreamWriter wr = new StreamWriter(FilePath))
{
xs.Serialize(wr,item);
}
}
}
public class DataBase
{
public static void DataCollectionChanged(object sender,System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
string name = \"N/A\";
if (sender is Entity) // will be called for EntityBase and ObservableCollection<ChildB> via ChildC
{
name = ((Entity)sender).Name;
}
Console.WriteLine(\"Collection changed: performed {0} on ({1}) of type {2}\",e.Action,name,sender.GetType().Name);
}
public static void DataPropertyChanged(object sender,PropertyChangedEventArgs e)
{
if (sender is Entity && e.PropertyName == \"Name\")
{
string name = ((Entity)sender).Name;
Console.WriteLine(\"Data Property Changed {0} to ({1}) on type {2}\",e.PropertyName,sender.GetType().Name);
}
}
public Node GetData()
{
Node childB1 = new Node { Name = \"Parent 1 - ChildB 1\" };
Node childB2 = new Node { Name = \"Parent 1 - ChildB 2\" };
Node childA1 = new Node { Name = \"Parent 1 - ChildA 1\",Children = new ObservableCollection<Entity>{childB1,childB2 }};
// ChildA will have ChildB objects as its child
Node childC = new Node { Name = \"ChildC\",Children = new ObservableCollection<Entity>()};
for (int i = 0; i < 5; i++)
{
//childC.
childC.Children.Add(new Node { Name = \"Pappu\" + i }); // childC children Property will have childB Object
}
Node parent1 = new Node { Name = \"Parent 1\",Children = new ObservableCollection<Entity>{ childC,childA1 }};
//Family 2
Node parentX = new Node { Name = \"Parent\",Children = new ObservableCollection<Entity> { parent1} };
return parentX;
}
}
class Program
{
static void Main(string[] args)
{
DataBase db = new DataBase();
Node data = db.GetData();
Util.SerializeObjectToXML<Node>(data,@\"d:\\tmp\\test.txt\");
}
}
}
控制台输出:
Data Property Changed Name to (Parent 1 - ChildB 1) on type Node
Data Property Changed Name to (Parent 1 - ChildB 2) on type Node
Data Property Changed Name to (Parent 1 - ChildA 1) on type Node
Data Property Changed Name to (ChildC) on type Node
Data Property Changed Name to (Pappu0) on type Node
Collection changed: performed Add on (N/A) of type ObservableCollection`1
Data Property Changed Name to (Pappu1) on type Node
Collection changed: performed Add on (N/A) of type ObservableCollection`1
Data Property Changed Name to (Pappu2) on type Node
Collection changed: performed Add on (N/A) of type ObservableCollection`1
Data Property Changed Name to (Pappu3) on type Node
Collection changed: performed Add on (N/A) of type ObservableCollection`1
Data Property Changed Name to (Pappu4) on type Node
Collection changed: performed Add on (N/A) of type ObservableCollection`1
Data Property Changed Name to (Parent 1) on type Node
Data Property Changed Name to (Parent) on type Node
Press any key to continue . . .
序列化的XML输出文件:
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<Node xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
<Name>Parent</Name>
<Children>
<Entity xsi:type=\"Node\">
<Name>Parent 1</Name>
<Children>
<Entity xsi:type=\"Node\">
<Name>ChildC</Name>
<Children>
<Entity xsi:type=\"Node\">
<Name>Pappu0</Name>
</Entity>
<Entity xsi:type=\"Node\">
<Name>Pappu1</Name>
</Entity>
<Entity xsi:type=\"Node\">
<Name>Pappu2</Name>
</Entity>
<Entity xsi:type=\"Node\">
<Name>Pappu3</Name>
</Entity>
<Entity xsi:type=\"Node\">
<Name>Pappu4</Name>
</Entity>
</Children>
</Entity>
<Entity xsi:type=\"Node\">
<Name>Parent 1 - ChildA 1</Name>
<Children>
<Entity xsi:type=\"Node\">
<Name>Parent 1 - ChildB 1</Name>
</Entity>
<Entity xsi:type=\"Node\">
<Name>Parent 1 - ChildB 2</Name>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
</Children>
</Node>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。