Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
86 views
in Technique[技术] by (71.8m points)

c# - How to create an application settings parameter of type a list of structs?

In my project I have a custom struct:

struct Point {
  public uint xPoint { get; }
  public uint yPoint { get; }

  public Point(uint x, uint y) {
    xPoint = x;
    yPoint = y;
  }
}

I'm using a list of these Points:

List<Point> pathToNavigate = new List<Point>();

What I'm trying to do is save a list of my Points to the Settings.settings: Like this

I can't figure out how to change string to be a list of my struct Point.

I tried messing with the xml and manually add in my option but I can't work out how to do it. Most things I find tell me to use a custom namespace but I also can't get that working with a list of my Point struct.

Edit: My problem is with a custom struct using a list. The issue isn't adding the items to the list, it's being able to load their contents properly.

question from:https://stackoverflow.com/questions/65848170/how-to-create-an-application-settings-parameter-of-type-a-list-of-structs

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The steps below work.

However, I believe your issue is simply because xPoint and yPoint do not have public setters. This is due to how XmlSerializer works. See the documentation here.

First, create a setting. In this case I named it ListOfPoints. The type is irrelevant, we're going to change it anyways.

Manually edit "Settings.settings". I just open it with Visual Studio's XML editor but use what you prefer.

Then change the type of the setting only. Note you need to use HTML encoding for < and >.

Entire Settings.settings:

<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="WindowsFormsApp1.Properties" GeneratedClassName="Settings">
  <Profiles />
  <Settings>
    <Setting Name="ListOfPoints" Type="System.Collections.Generic.List&lt;WindowsFormsApp1.MyPoint&gt;" Scope="User">
      <Value Profile="(Default)" />
    </Setting>
  </Settings>
</SettingsFile>

The only change made was this:

Type="System.Collections.Generic.List&lt;WindowsFormsApp1.MyPoint&gt;"

All Code:

[Serializable]
public struct MyPoint
{
    public uint X { get; set; }
    public uint Y { get; set; }

    public MyPoint(uint x, uint y)
    {
        X = x;
        Y = y;
    }

    public override bool Equals(object obj)
    {
        if (!(obj is MyPoint))
            return false;
        var other = (MyPoint)obj;
        return other.X == X && other.Y == Y;
    }

    public override int GetHashCode()
    {
        return unchecked(X.GetHashCode() ^ Y.GetHashCode());
    }
}

private static readonly List<MyPoint> saveMe = new List<MyPoint>();
private static List<MyPoint> loadMe;

private static void SaveData()
{
    Properties.Settings.Default.ListOfPoints = saveMe;
    Properties.Settings.Default.Save();
}

private static void LoadData()
{
    Properties.Settings.Default.Reload();
    loadMe = Properties.Settings.Default.ListOfPoints;
    TestData();
}

private static void TestData()
{
    if (loadMe.Count != saveMe.Count)
        throw new Exception("Different counts");
    for (int i = 0; i < loadMe.Count; i++)
    {
        if (!loadMe[i].Equals(saveMe[i]))
            throw new Exception($"{nameof(MyPoint)} at index {i} doesn't match");
    }
}

Test this by adding whatever you wish to saveMe. Then run SaveData followed by LoadData.

LoadData will throw an exception if the data doesn't match.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...