C# Streamreader problems - c#

I'm building a program that has you input a number and remembers it when you re-open the program. It uses a text file to save the number in. I'm using streamreader to read the text file to get the number you entered last, but it always throws an exception. Where should I put the text file or change my code so it can read and edit the text? Here is my code:
namespace Cookie_Clicker
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void tb_TextBox(object sender, RoutedEventArgs e)
{
}
private void add_Click(object sender, RoutedEventArgs e)
{
try
{
using (StreamReader sr = new StreamReader("cookies.txt"))
{
int data = Convert.ToInt16(sr.ReadToEnd());
tb.Text = Convert.ToString(data + 1);
}
}
catch (Exception)
{
MessageBox.Show("Your cookie text file is missing!");
}
}
private void reset_Click(object sender, RoutedEventArgs e)
{
}
}
}

Every time it says "Your cookie text file is missing!"
Problem 1: You are not specifying proper path of your input file.
Solution 1: You need to get the Currentpath of your application from where it is running and then combine it with the filename using Path.Combine() method.
Try This:
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"cookies.txt");
using (StreamReader sr = new StreamReader(path))
{
int data = Convert.ToInt16(sr.ReadToEnd());
tb.Text = Convert.ToString(data + 1);
}
Suggestion : You need to always display the Error message in Catch block to identify the problem.
You can call ToString() on Exception object to get the complete exception info.
catch (Exception ex)
{
MessageBox.Show(ex.ToSTring();
}

To answer your question:
Where should I put the text file...?
You haven't specified a path to cookies.txt so the program will look for it in the same directory where it's running. If you change cookies.txt to include a path, for example C:\dev\cookies.txt, then you can store the file wherever you like.
That will allow you to get past the file not found error and address any other problems you have in there.

Related

Try-catch not working loading XAML resource

I have these pieces of code:
private void btnPlanning_Click(object sender, RoutedEventArgs e)
{
LoadPage("PlanningView.xaml");
}
private void LoadPage(string APage)
{
try
{
frameMainView.Source = new Uri(APage, UriKind.Relative);
}
catch (Exception ex)
{
string errorString = $"Resource <{APage}> not found! ";
DoLogD(errorString + " " + ex.Message);
MessageBox.Show(errorString);
}
}
Clicking on btnPlanning button, LoadPage is called passing a string with the name of the XAML resource I want to load in the frame control frameMainView.
If the given resource doesn't not exist, I would like to catch the exception and inform the user.
The problem is that when i click the button (and the resource doesn't exist), I get in any case
PresentationFramework.pdb not loaded
and a internal System.IO.IOException telling me the resource is not available.
Why my try-catch block is not working?
there are many ways to load the pages into the frame:
By setting the source
frameMainView.Source = new Uri("PlanningView.xaml",UriKind.RelativeOrAbsolute);
By setting the Content:
frameMainView.Content= new PlanningView();
By using the NavigationService:
frameMainView.NavigationService.Navigate(new PlanningView());
It´s a user interface initialization Problem. Can you get more information from the visual Studio "Output" Window?

load from a txt to a list box in C#

I already have the saving part down and I know it works, but when I click load button, it will not display anything that I have saved from the text boxes that go to the saying.txt file
using System;
using System.IO;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Grades : Form
{
private StreamWriter fil;
public Grades()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
fil = new StreamWriter("saying.txt"); //This is the txt file
}
catch (DirectoryNotFoundException exc)
{
lstBxDisplay.Text = "Nothing " +
exc.Message;
}
catch (System.IO.IOException exc)
{
lstBxDisplay.Text = exc.Message;
}
}
// saving the files to the saying.txt
private void btnSaveAs_Click(object sender, EventArgs e)
{
try
{
fil.WriteLine(txtBxLastName.Text);
txtBxLastName.Text = "";
txtBxLastName.Focus();
}
catch (System.IO.IOException exc)
{
lstBxDisplay.Text = exc.Message;
}
}
// next is the load button to load the files into the list/display box
private void btnLoad_Click(object sender, EventArgs e)
{
string inValue;
try
{
using (StreamReader infil =
new StreamReader("saying.txt"))
{
inValue = infil.ReadLine();
while (inValue != null)
{
inValue = infil.ReadLine();
if (inValue != null)
this.lstBxDisplay.Items.Add(inValue);
} // end of while
} // end of using
}
catch (System.IO.IOException exc)
{
lstBxDisplay.Text = exc.Message;
}
}
private void Grades_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
fil.Close();
}
catch
{
}
}
}
}
any reason why it is not loading into the list box? I have tried both label and text box to display the message and neither of them work. I debugged the program and it is executing fine
You have multiple issues here but I will point out two main issues that will get your code working.
You are not closing the stream when you try to save. If the stream stays open, you will never be able to read the values when you try to "Load" the file. You need to call fil.Close(); at the end of your btnSaveAs_Click method.
This is how the save should read.
fil.WriteLine(txtBxLastName.Text);
txtBxLastName.Text = "";
txtBxLastName.Focus();
fil.Close();
You're skipping the first line of the file in your "Load" method. You call infil.ReadLine(); then in the loop, you call it again before you add it to your listbox. You need to move your second ReadLine(). If you are only ever writing a single line to the file, your existing code will skip that first line and try to read it again which will be null (no second line). So, it will never add anything to your listbox.
This is how the reads should be ordered.
using (StreamReader infil = new StreamReader("saying.txt"))
{
inValue = infil.ReadLine();
while (inValue != null)
{
this.lstBxDisplay.Items.Add(inValue);
inValue = infil.ReadLine();
} // end of while
} // end of using
Those changes will get you working. Now to point out, you are going about reading and writing to a file all wrong. You should not be opening a stream in your form load and waiting for button clicks to be writing/reading from that stream. Unless you have a very good reason to do what you are doing, you should be opening your stream, performing the read/write operation, and closing your stream right away. For a simple file IO, I would even suggest using a different mechanism. Look at the MSDN for the System.IO.File Class for easier methods to read lines or write lines to a file.

How to write into same xml file from two pages?

I have Single.cs and Periodic.cs files, which have Button_Click events, and user should add some information into same file by pressing these buttons. Implementation of Button_Click is almost same, this is why I show only one them.
using System.IO;
//.........
namespace ModernUIApp1.Pages
{
public partial class Home : UserControl
{
private void Button_Click(object sender, RoutedEventArgs e)
{
// this is how i get required path
var systemPath = System.Environment.GetFolderPath(
Environment.SpecialFolder.CommonApplicationData);
var _directoryName1 = Path.Combine(systemPath, "RadiolocationQ");
string script = "script";
string path_scriprt1 = Path.Combine(_directoryName1, script+".xml");
cur_script.Add(new XElement("Single_Request" + Convert.ToString(num),
new XElement("numRequest", TxtBlock_numRequest.Text),
));
cur_script.Save(path_scriprt1);
num++; // I use this to create unique name
}
XElement cur_script = new XElement("Requestes");
int num = 1;
}
}
Eventually, user can push buttons many times, and this code will work fine if I dont use these buttons at the same time. Because otherwise it simply overwrites existing information. So the problem is to make this XElement cur_script = new XElement("Requestes"); global. Or do you have some other ways out?
The real issue is that you need to avoid concurrency issue here. What if you have two persons try to update the same file and the following sequences occurs:
User 1 open and load the file;
User 2 open and load the file;
User 1 modify the xml and save it;
User 2 modify the xml and save it;
In this case the change made by user 1 will be lost.
To avoid this problem you want to keep the file open until your have saved it. For example:
using (FileStream stream =
File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
....load xml, modify it, and save it
}
public void WriteToDoc(XmlDocument doc, XElement element)
{
// this method can reside somewhere outside.
// some generic doc loader can load the doc
// add element to doc
}
public void OnButton1Click(object sender, RoutedEventArgs e)
{
// do something with element
WriteToDoc( mydoc, myNewElement)
}
public void OnButton2Click(object sender, RoutedEventArgs e)
{
// do something else with element
WriteToDoc( mydoc, myNewElement)
}
V2
public class ElementAdder
{
public static void WriteToDoc(string path, XElement element)
{
// load doc based on path
// add element to doc
}
}
public void OnButton1Click(object sender, RoutedEventArgs e)
{
// do something with element
string path = ConfigMan.GetDocPath();
ElementAdder.WriteToDoc(path, myNewElement);
}
public void OnButton2Click(object sender, RoutedEventArgs e)
{
// do something else with element
string path = ConfigMan.GetDocPath();
ElementAdder.WriteToDoc(path, myNewElement);
}
Thank you for help, but I solved problem on my own. I just used tips how to write into same xml-file, this way:
XDocument Requestes = XDocument.Load(path_scriprt1);
XElement newElement = new XElement("Single_Request" + Convert.ToString(num),
new XElement("numRequest", TxtBlock_numRequest.Text),
new XElement("IDWork", TxtBlock_IDWork.Text),
new XElement("NumObject", TxtBlock_NumObject.Text),
new XElement("lvlPriority", CmbBox_lvlPriority.Text),
new XElement("NumIn1Period", TxtBlock_NumIn1Period.Text)
);
Requestes.Descendants("Requestes").First().Add(newElement);
Requestes.Save(path_scriprt1);

How to catch the control name that caused exception in C#?

I have few text boxes that should allow a certain format, but when a user enters it in a wrong format in a textbox, I would like to catch the control name and clear the text of the textbox.
Clearing the user input because it's not in a given format is very user-unfriendly. What if only one of ten characters was wrong? They'd have to type it all over again. Just use a MaskedTextBox with a Mask for the pattern you expect.
When using a MaskedTextBox, you can subscribe to the MaskInputRejected event as described here:
public void Form1_Load(Object sender, EventArgs e)
{
... // Other initialization code
maskedTextBox1.Mask = "00/00/0000";
maskedTextBox1.MaskInputRejected += new MaskInputRejectedEventHandler(maskedTextBox1_MaskInputRejected)
}
void maskedTextBox1_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
{
toolTip1.ToolTipTitle = "Invalid Input";
toolTip1.Show("We're sorry, but only digits (0-9) are allowed in dates.", maskedTextBox1, maskedTextBox1.Location, 5000);
}
Throwing exceptions for expected behaviour is never right as they are very expensive. If you need to see where the exception originated just check the top line of the stack trace.
debug only
you can get control name in debug mode from the yourForm.cs . i dont think this code will run on relese cuz. the source file wont be in ther release right?
using System.Diagnostics;
public void ParseControlText()
{
try
{
var doubleval = Double.Parse(tb_double.Text);
var intval = Int32.Parse(tb_int.Text);
//... bunch of controls need to be parssed to calculate something
}
catch (FormatException ex)
{
var stlast = new StackTrace(ex,true).GetFrames().Last();
//this requires form.cs to exist . how am i gonna do this in release? idk
var stLine = File.ReadLines(stlast.GetFileName())
.ToList()[stlast.GetFileLineNumber()-1];
var m = Regex.Match(stLine ,#"\((.*?)\..*?\)");
var ctrlname = m.Groups[1].Value;
MessageBox.Show( ctrlname + " control's text coundnt be Parsed! " );
}
}

Save Contents Of a TextBox To a File

I'm developing an application that has a TextBox. I want to write its contents to a file, but how can I do this?
There are many ways to accomplish this, the simplest being:
using(var stream = File.CreateText(path))
{
stream.Write(text);
}
Be sure to look at the MSDN page for File.CreateText and StreamWriter.Write.
If you weren't targeting the .NET Compact Framework, as your tags suggest, you could do even simpler:
File.WriteAllText(path, string);
System.IO.File.WriteAllText("myfile.txt", textBox.Text);
If you're stuck on some brain-dead version of the BCL, then you can write that function yourself:
static void WriteAllText(string path, string txt) {
var bytes = Encoding.UTF8.GetBytes(txt);
using (var f = File.OpenWrite(path)) {
f.Write(bytes, 0, bytes.Length);
}
}
Try this:
using System.Text;
using System.IO;
static void Main(string[] args)
{
// replace string with your file path and name file.
using (StreamWriter sw = new StreamWriter("line.txt"))
{
sw.WriteLine(MyTextBox.Text);
}
}
Of course, add exception handling etc.
For a richTextBox, you can add a "Save" button for this purpose. Also add a saveFileDialog control from Toolbox, then add following code in button's click event.
private void button1_Click(object sender, EventArgs e)
{
DialogResult Result = saveFileDialog1.ShowDialog();//Show the dialog to save the file.
//Test result and determine whether the user selected a file name from the saveFileDialog.
if ((Result == DialogResult.OK) && (saveFileDialog1.FileName.Length > 0))
{
//Save the contents of the richTextBox into the file.
richTextBox1.SaveFile(saveFileDialog1.FileName);
}
}

Categories

Resources