2010-06-16 89 views
3

您可以將對象保存到Visual Studio中的settings.settings文件中嗎?如果是這樣如何?我認爲你可以讓你的對象可序列化並且它應該持久化,但是我不知道我是否正確地做了這件事,即當我試圖獲取對象時,它總是空的。如何將對象保存到Visual Studio中的fooSettings.settings文件中?

下面是代碼:

[Serializable()] 
    [XmlRoot(ElementName = "LayerTCA", IsNullable = false, Namespace = "http://somesite.com")] 
    public class LayerTCA 
    { 
     //This is a COM object so I don't want to serialize this. 
     IFeatureClass featureClass; 

     string fullName; 
     string basicName; 

     public LayerTCA() 
     { 

     } 

     public LayerTCA(IFeatureClass featureClass) 
     { 
      FeatureClass = featureClass; 
     } 


     public IFeatureClass FeatureClass 
     { 
      get { return featureClass; } 
      set 
      { 
       featureClass = value; 
       fullName = featureClass.AliasName; 
       basicName = StringHelper.StringAfterLastFullStop(fullName); 
      } 
     } 

     [XmlAttribute(AttributeName = "BasicName")] 
     public string BasicName 
     { 
      get { return basicName; } 
      set { basicName = value; } 
     } 


     [XmlAttribute(AttributeName = "FullName")] 
     public string FullName 
     { 
      get { return fullName; } 
      set { fullName = value; } 
     } 

     public override string ToString() 
     { 
      return FullName; 
     } 

    } 
+0

你可以添加序列化/反序列化代碼嗎? – Rox 2010-06-16 11:20:32

+0

它只是靜態調用fooSettings.settings來保存對象,即 var layerTCA = new LayerTCA(); fooSettings.settings.Default.myLayerTCA = layerTCA; 然後反過來檢索。 – Vidar 2010-06-16 12:45:43

+0

這裏一點更新:我嘗試了一些測試,似乎你可以在Settings.setting文件只要保存一個類你自己的,因爲它沒有像它一個COM變量。必須有某種方法來對FeatureClass進行賦值,以便在序列化時忽略它。 – Vidar 2010-06-16 15:24:06

回答

1

我會使用一個成員變量,其爲IFeatureClassName。構造函數將接受一個I​​Featureclass,然後將要素類轉換爲IDataset並將該成員變量設置爲IDataset.FullName。這將是一個IName。所有的IName對象都可以通過IPersistStream持久保存。儘管不能直接對xml進行序列化,但可以將IPersistStream對象寫入byte [](通過MemoryBlobStream)。不記得byte []是否可以通過XmlAttribute暴露,可能應該使用base64。可能還有一個Open方法將簡單地調用IName.Open包含的成員featureclassname變量,返回一個IFeatureclass。

更新:這裏有一些代碼可能有助於將要素類名轉換爲字符串和從字符串轉換。

public static void TestIt(IFeatureClass fc) 
{ 
    string guidplusbase64Name = GetFullName((IDataset)fc); 
    Debug.Print(guidplusbase64Name); 
    IFeatureClass fc2 = OpenDataset(guidplusbase64Name) as IFeatureClass; 
    Debug.Print(fc2.AliasName);    
} 

public static string GetFullName(IDataset ds) 
{ 
    IPersistStream ps = ds.FullName as IPersistStream; 
    Guid g; 
    ps.GetClassID(out g);    
    IMemoryBlobStream mbs = new MemoryBlobStreamClass(); 
    ps.Save(mbs,0); 
    object bytes; 
    ((IMemoryBlobStreamVariant)mbs).ExportToVariant(out bytes);    
    return String.Format("{0};{1}",g,Convert.ToBase64String((byte[])bytes)); 
} 

public static IDataset OpenDataset(string guidplusbase64Name) 
{ 
    int idx = guidplusbase64Name.IndexOf(";"); 
    string base64Name = guidplusbase64Name.Substring(idx+1); 
    string guidString = guidplusbase64Name.Substring(0, idx); 

    byte[] bytes = Convert.FromBase64String(base64Name); 
    IMemoryBlobStream mbs = new MemoryBlobStreamClass(); 
    ((IMemoryBlobStreamVariant)mbs).ImportFromVariant(bytes); 
    Type t = Type.GetTypeFromCLSID(new Guid(guidString)); 
    IName n = Activator.CreateInstance(t) as IName; 
    ((IPersistStream)n).Load(mbs); 
    IDataset ds = n.Open() as IDataset; 
    return ds; 
} 

(更新任何IDataset工作,不只是featureclasses) (UPDATE2:串聯的CLSID允許它與任何數據集工作,以前的版本是硬的featureclassname)

別問我爲何ESRI尚未實施IName.NameString

NameString屬性保留爲 供將來使用。當被實施時,它 將返回的 字符串表示可由 應用持久保存的名稱 對象的區位分量。

+0

這看起來很有趣 - 我現在仔細看看... – Vidar 2010-06-16 15:25:17

相關問題