2017-12-28 20 views
1

カスタム設定プロバイダを使用して次のクラスを保存しようとしていますが、null参照エラーが続いています(下記のエラーの詳細)。カスタム設定プロバイダでカスタムクラスをシリアライズ

[Serializable] 
public class SoundClips 
{ 

    [System.Xml.Serialization.XmlElementAttribute("Items")] 
    public List<SoundKeyBind> Items { get; set; } 

    public SoundClips() 
    { 
     Items = new List<SoundKeyBind>(); 
    } 

} 

[Serializable] 
public class SoundKeyBind 
{ 
    public string FilePath { get; set; } 
    public string FileName { get; set; } 
    public string KeyBindText { get; set; } 
    public KeyPressedEventArgs KeyBind { get; set; } 
} 

によって救わ:

 dgvSoundBoard.DataSource = keyBinds.Items; 
     Properties.Settings.Default.SoundBinds = keyBinds; 
     Properties.Settings.Default.Save(); 

私はどこかGitHubの上で次の設定プロバイダを得たが、申し訳ありませんが、それを参照するためのリンクを見つけることができません。それがnullであるpropertyValue.SerializedValue.ToString()にアクセスしようとしたとき

public sealed class MySettingsProvider : SettingsProvider, IApplicationSettingsProvider 
{ 
    private const string _rootNodeName = "settings"; 
    private const string _localSettingsNodeName = "localSettings"; 
    private const string _globalSettingsNodeName = "globalSettings"; 
    private const string _className = "MySettingsProvider"; 
    private XmlDocument _xmlDocument; 

    private string _filePath 
    { 
     get 
     { 
      return Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), 
       string.Format("{0}.settings", ApplicationName)); 
     } 
    } 

    private XmlNode _localSettingsNode 
    { 
     get 
     { 
      XmlNode settingsNode = GetSettingsNode(_localSettingsNodeName); 
      XmlNode machineNode = settingsNode.SelectSingleNode(Environment.MachineName.ToLowerInvariant()); 

      if (machineNode == null) 
      { 
       machineNode = _rootDocument.CreateElement(Environment.MachineName.ToLowerInvariant()); 
       settingsNode.AppendChild(machineNode); 
      } 

      return machineNode; 
     } 
    } 

    private XmlNode _globalSettingsNode 
    { 
     get { return GetSettingsNode(_globalSettingsNodeName); } 
    } 

    private XmlNode _rootNode 
    { 
     get { return _rootDocument.SelectSingleNode(_rootNodeName); } 
    } 

    private XmlDocument _rootDocument 
    { 
     get 
     { 
      if (_xmlDocument == null) 
      { 
       try 
       { 
        _xmlDocument = new XmlDocument(); 
        _xmlDocument.Load(_filePath); 
       } 
       catch (Exception) 
       { 

       } 

       if (_xmlDocument.SelectSingleNode(_rootNodeName) != null) 
        return _xmlDocument; 

       _xmlDocument = GetBlankXmlDocument(); 
      } 

      return _xmlDocument; 
     } 
    } 

    public override string ApplicationName 
    { 
     get { return Path.GetFileNameWithoutExtension(Application.ExecutablePath); } 
     set { } 
    } 

    public override string Name 
    { 
     get { return _className; } 
    } 

    public override void Initialize(string name, NameValueCollection config) 
    { 
     base.Initialize(Name, config); 
    } 

    public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) 
    { 
     foreach (SettingsPropertyValue propertyValue in collection) 
      SetValue(propertyValue); 

     try 
     { 
      _rootDocument.Save(_filePath); 
     } 
     catch (Exception) 
     { 
      /* 
      * If this is a portable application and the device has been 
      * removed then this will fail, so don't do anything. It's 
      * probably better for the application to stop saving settings 
      * rather than just crashing outright. Probably. 
      */ 
     } 
    } 

    public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection) 
    { 
     SettingsPropertyValueCollection values = new SettingsPropertyValueCollection(); 

     foreach (SettingsProperty property in collection) 
     { 
      values.Add(new SettingsPropertyValue(property) 
      { 
       SerializedValue = GetValue(property) 
      }); 
     } 

     return values; 
    } 

    private void SetValue(SettingsPropertyValue propertyValue) 
    { 
     XmlNode targetNode = IsGlobal(propertyValue.Property) 
      ? _globalSettingsNode 
      : _localSettingsNode; 

     XmlNode settingNode = targetNode.SelectSingleNode(string.Format("setting[@name='{0}']", propertyValue.Name)); 

     if (settingNode != null) 
      settingNode.InnerText = propertyValue.SerializedValue.ToString(); 
     else 
     { 
      settingNode = _rootDocument.CreateElement("setting"); 

      XmlAttribute nameAttribute = _rootDocument.CreateAttribute("name"); 
      nameAttribute.Value = propertyValue.Name; 

      settingNode.Attributes.Append(nameAttribute); 

      // ######### ERROR OCCURS HERE ######### 
      settingNode.InnerText = propertyValue.SerializedValue.ToString(); 
      // ######### ERROR OCCURS HERE ######### 

      targetNode.AppendChild(settingNode); 
     } 
    } 

    private string GetValue(SettingsProperty property) 
    { 
     XmlNode targetNode = IsGlobal(property) ? _globalSettingsNode : _localSettingsNode; 
     XmlNode settingNode = targetNode.SelectSingleNode(string.Format("setting[@name='{0}']", property.Name)); 

     if (settingNode == null) 
      return property.DefaultValue != null ? property.DefaultValue.ToString() : string.Empty; 

     return settingNode.InnerText; 
    } 

    private bool IsGlobal(SettingsProperty property) 
    { 
     foreach (DictionaryEntry attribute in property.Attributes) 
     { 
      if ((Attribute)attribute.Value is SettingsManageabilityAttribute) 
       return true; 
     } 

     return false; 
    } 

    private XmlNode GetSettingsNode(string name) 
    { 
     XmlNode settingsNode = _rootNode.SelectSingleNode(name); 

     if (settingsNode == null) 
     { 
      settingsNode = _rootDocument.CreateElement(name); 
      _rootNode.AppendChild(settingsNode); 
     } 

     return settingsNode; 
    } 

    public XmlDocument GetBlankXmlDocument() 
    { 
     XmlDocument blankXmlDocument = new XmlDocument(); 
     blankXmlDocument.AppendChild(blankXmlDocument.CreateXmlDeclaration("1.0", "utf-8", string.Empty)); 
     blankXmlDocument.AppendChild(blankXmlDocument.CreateElement(_rootNodeName)); 

     return blankXmlDocument; 
    } 

    public void Reset(SettingsContext context) 
    { 
     _localSettingsNode.RemoveAll(); 
     _globalSettingsNode.RemoveAll(); 

     _xmlDocument.Save(_filePath); 
    } 

    public SettingsPropertyValue GetPreviousVersion(SettingsContext context, SettingsProperty property) 
    { 
     // do nothing 
     return new SettingsPropertyValue(property); 
    } 

    public void Upgrade(SettingsContext context, SettingsPropertyCollection properties) 
    { 
    } 
} 

エラーがprivate void SetValue(SettingsPropertyValue propertyValue)で、[設定]プロバイダで発生します。私は上記のコードで、その場所を強調するためにコメントしています。エラーは次のとおりです。私はMySettingsProviderに設定のプロバイダを設定し、Trueにローミング設定された設定デザイナで

An unhandled exception of type 'System.NullReferenceException' occurred in SoundBoard.exe Object reference not set to an instance of an object.

。私は、クラスの直列化宣言と間違って何かを持っていることを推測しているが、私は、たとえば、いくつかのことを試してみた:

[Serializable] 
[SettingsSerializeAs(SettingsSerializeAs.Xml)] 
public class SoundClips 

をし、それを把握することはできません。

ご協力いただければ幸いです。

答えて

0

クラスを分割して各ビットを1つずつ保存することで、問題を解決することができました。問題は、SoundKeyBindクラスとその中で作成されたKeyPressedEventArgsクラス/オブジェクトがパラメータを取らないコンストラクタを必要とすることが判明しました。

I.e.私は、それぞれのクラスに以下を追加する必要:

public SoundKeyBind() { } 

public KeyPressedEventArgs() { } 
関連する問題