0

I wanna read the location of a text file so when I reopen my Form it should be at the location I last closed it. Any way to do that?

My code to write into text files:

string path = Directory.GetCurrentDirectory() + @"\config\Loc\dateloc.txt";

if (!File.Exists(path))
{
    File.Create(path);
}

try
{
    System.IO.File.WriteAllBytes(path, new byte[0]);
    StreamWriter writer = new StreamWriter(path, true);
    string overlayloc = this.Location.ToString();
    writer.WriteLine(overlayloc.ToString());
    writer.Dispose();
    writer.Close();
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString());
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Vulpi
  • 1
  • Why do you start writing a byte in that file? Also StreamWriter creates the file if it doesn't exist. Finally you write in append mode, are you writing in that file more locations than the one of the current form? – Steve Jan 17 '21 at 16:09
  • well, first you have to determine\clarify whether this **Setting** Is to be app, machine or user specific, then also whether it is control specific. Essentially, what scope? – Brett Caswell Jan 17 '21 at 16:14
  • `visual-studio-2019` ← *Do not use this tag unless you have a specific question about this specific version.* – Reza Aghaei Jan 17 '21 at 16:15
  • @RezaAghaei generally, I agree.. but one answer to this is actually going to be IDE specific, since it will generate code when working with Settings through the designer, and you wouldn't open up the question to how every IDE version designer might otherwise handle it. As such, the question is a bit ambiguous, because there are many ways to implement this. – Brett Caswell Jan 17 '21 at 16:18
  • + Ditch `Directory.GetCurrentDirectory()`, you don't know what is the *Current* directory. What's *current* can change at any time. If you mean the Application's startup path, that's `Application.StartupPath` in WinForms. Then use `Path.Combine()` to build a path, don't concatenate strings. -- Either use `File.WriteAllText()` / `File.WriteAllLines()` or a StreamWriter, not both. – Jimi Jan 17 '21 at 16:29
  • @BrettCaswell here is my idea: VS tags should be used for VS specific questions as a software or for cases that something behave differently in different VS versions. We don't tag all C# questions with VS tag because we create .cs files in VS or all WinForms questions because of VS designer? I understand that VS gives you some designer support for Settings files but setting is a feature of framework not VS and unless you have a specific question of Settings designer in VS2019 (for example it works in VS2017 but not in VS2019), you usually should not tag it with VS2019. Does that makes sense? – Reza Aghaei Jan 17 '21 at 16:33
  • 1
    Does this answer your question? [How to remember a variable at each startup?](https://stackoverflow.com/questions/58577254/how-to-remember-a-variable-at-each-application-startup) and [Save Settings in Winforms](https://stackoverflow.com/questions/3032492/save-settings-in-a-net-winforms-application) and [What is the best way to store user settings?](https://stackoverflow.com/questions/26369/what-is-the-best-way-to-store-user-settings-for-a-net-application) and [Remember windows size and location](https://stackoverflow.com/questions/1873658/net-windows-forms-remember-windows-size-and-location) –  Jan 17 '21 at 16:38
  • 1
    Tutorials on CodeProject to use Application Settings and Visual Studio RAD Designers: [Windows Forms User Settings in C#](https://www.codeproject.com/Articles/15013/Windows-Forms-User-Settings-in-C) and [Restore Form Position and Size in C#](https://www.codeproject.com/Articles/25510/Restore-Form-Position-and-Size-in-C) –  Jan 17 '21 at 16:42

3 Answers3

0

get the value from file in constructor if file exist read the data get x y location and assign to location sorry for not able to understand your question in first glance i hope this works now

public Form1()
 {
            InitializeComponent();
            string path = Environment.CurrentDirectory + @"\config\dateloc.txt";
            if (File.Exists(path))
            {
                string loc = File.ReadAllText(path);
                this.Location = new Point(Int32.Parse(loc.Split(',')[0].Replace("{X=", "")), Int32.Parse(loc.Split(',')[1].Replace("Y=", "").Replace("}\r\n","")));
            }
 }
sai kiran
  • 389
  • 2
  • 10
  • yep.. though this may not be the best\recommended method of doing this, it is a straight forward answer (given the implementation the OP has for writing the contents). Essentially it addresses\answers how and where to parse `this.Location.toString()` given it was written to file. – Brett Caswell Jan 17 '21 at 17:33
0

Given your sample and approach, the answer you were probably initially looking for is provided by @sai kiran.

That is, you're doing ToString() of Form.Location (which is a System.Drawing.Point type) and you're writing that to a file in your approach. Note: the output string of ToString() is (X=?,Y=?), where ? is numerical characters representing the value.

Given that you are storing Location Point value that way (and not the serialized form of Point) and In order to achieve your desire result, you'll need to read that file and parse\handle the string represented value, constructing a new Point type instance from it, then assign it to Location before the form is shown.

There is NO standard Point.Parse method for this ToString string representation of Point (that I'm aware of), so you'll have to handle it with string manipulations and extrapolations. Note: if it was represented as "0, 0", you could deserialize it to Point type instance


Having said that, you can accomplish this task without specifically implementing File\Stream reads\writes nor parsing the extrapolated values of a string by using Application Settings and control Property Binding.

And actually, Using Application Settings and Property Binding is my recommended approach and answer here. I'll provide some instruction on doing that:

You'll define a Setting (for example "Form1LocationPointUserSetting") as a System.Drawing.Point in the scope of User. Since Point is a value type, it will have a default value - (0, 0)

You can define setting in a couple ways, but the easiest is probably using the Settings Designer tool of your IDE (it will generate code and update App.config)

Screenshot of Settings Designer

After saving settings designer changes (with CTRL+S to save all), you will be able to both programmatically reference to the Setting property name in code and use it in control property bindings (as it relates to the Type of Property it is). Note: not all control properties support binding in this manner, and some control properties that support bind may not implement\update with INotifyProperty changes.

Screenshot of Property Binding with Application Settings

Lastly, you'll want to persist any changes you've made to settings. So you'll call Property.Settings.Default.Save() during some event. (such as form closing event.)

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            FormClosing += Form1_FormClosing;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //Save Settings
            Properties.Settings.Default.Save();
        }
    }
Brett Caswell
  • 1,486
  • 1
  • 13
  • 25
-1

try changing

File.Create(path);

to

File.Create(path).Close();
sai kiran
  • 389
  • 2
  • 10