How can I pull a destination from a textbox? C# - c#

I have a textbox that generates a code based on the selections made by the user. I would like each possible code to correlate with copying and moving a folder into another. The folder is chosen by another textbox that allows the user to manually select the path for the new files to be moved to. What I am looking to do is set up a string of if/else if statements for each of the possible codes from textbox1. Take a look at my code below and see wha tyou find. Everything seems to work except for my statements uder
Private void button1_click...
private void button1_Click(object sender, EventArgs e)
{
string destination = textBox1.Text;
if (textBox2.Text == "111")
String sourceFile = (#"C:\Program Files (x86)\OrganizerPro\TFSN Internal Advisor to SWAG PPW");
System.IO.File.Move(sourceFile, destination);
}

Your immediate problem might just be one of scoping, it looks like you try the move even if the if failed to set the value.
A list of If/else is not a very maintainable solution, you'll need to rebuild and redeploy each time the list of possibilities changes. Avoid this by reading the list from something that is external to the application.
However, what you describe is essentially a mapping between a code and a filename.
If your mapping really is static and you're happy for it to be baked into the application then you could define the mapping like this
private Dictionary<string, string> mapping = new Dictionary<string, string>
{
{ "111", #"c:\Program Files\File 1.txt" },
{ "112", #"c:\Program Files\File 2.txt" },
{ "113", #"c:\Program Files\File 3.txt" },
};
You can retrieve values using some simple Linq
var codeLookup = mapping.FirstOrDefault(kv => kv.Key == textBox2.Text);
if (codeLookup.Key != null)
{
System.IO.File.Move(codeLookup.Value, destination);
}

Your question is not very clear. But there is something not logic in your code. this is a code behind method so change the method's access modifier from private to protected or public cause the event click does not reach this method
private void button1_Click(object sender, EventArgs e)
to
protected void button1_Click(object sender, EventArgs e)

Related

Insert chosen directory as a string into another method c#

I will spare you for a big background story to the program I'm creating here.
image
As the picture shows:
How do i get the directory result from the lowest method into the one above as a path string?
One way to do the job is by having a global variable like this:
string dir = ""; //Default
private void SelectDir_Click(object sender, EventArgs e)
{
//Open dialog and in dialog ok set dir
dir=dialog.Path;
}
private void UserValue_Click(object sender, EventArgs e)
{
var path=dir+"\\fileName.txt";
}
I was to lazy to type a code like yours but you'll get it :)
First, declare the variable to store your string.
private string userSelectedPath = "";
Create the FolderBrowserDialog:
xmodialog = new FolderBrowserDialog();
Check the result and retrieve the path selected by the user:
var result = xmodialog.ShowDialog();
if (result == DialogResult.OK)
{
userSelectedPath = xmodialog.SelectedPath;
}
Finally, you can use the stored path however you like:
File.WriteAllText(..., "A6_DRV_EDI=" + userSelectedPath);
It is up to you to enforce that the user first selects the path and only then uses it.

Keeping the main form tidy - conventions

This is not a question about coding per se but about good practice in code structure. I'm currently building a WinForms application and already after a few hours in, my main form contains 130 lines of code. That might not be much but this only includes event handling - since I tried to avoid this exact situation by having seperate class files for basically everything ... but right now all the controls and events just make my main code pretty hard to read.
Now this is a topic I could find surprisingly little on and I do have some ideas on how to tackle this, like creating custom controls and splitting up the form into big portions. Is there a sort of best practice for this? How do you keep your main form clean when 80% of user interaction takes place here? Also is there a basic guideline on how to structure a project (not code) you can recommend?
(Hope this qualifies as a valid question)
Thanks!
EDIT: I decided to add in the code. See anything redundand?
public partial class MainForm : Form
{
string currentFilter = "all";
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, System.EventArgs e)
{
RefreshGenres();
RefreshMovies(currentFilter);
}
private void addToolStripMenuItem_Click(object sender, System.EventArgs e)
{
var fAdd = new AddNewForm();
fAdd.SetDesktopLocation(MousePosition.X, MousePosition.Y);
fAdd.ShowDialog();
}
private void refreshToolStripMenuItem_Click(object sender, System.EventArgs e)
{
RefreshGenres();
RefreshMovies(currentFilter);
}
private void addCategoryToolStripMenuItem_Click(object sender, System.EventArgs e)
{
tvCategories.Nodes.Add(new TreeNode("category"));
tvCategories.Nodes[tvCategories.Nodes.Count - 1].BeginEdit();
}
private void tvCategories_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
{
var genre = e.Label;
var writer = new Writer();
writer.AddGenre(e.Label);
}
private void everythingToolStripMenuItem_Click(object sender, System.EventArgs e)
{
EraseData("all");
}
private void clearGenres_Click(object sender, System.EventArgs e)
{
EraseData("genres");
}
private void clearMovies_Click(object sender, System.EventArgs e)
{
EraseData("movies");
}
private void EraseData(string eraseThis)
{
DialogResult r = MessageBox.Show("Are you sure?\nLost data can NOT be retrieved.", "Clear Data", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
var cmdText = "";
if (r == DialogResult.Yes)
{
switch (eraseThis)
{
case "all":
cmdText = "TRUNCATE TABLE MOVIES GENRES";
break;
case "movies":
cmdText = "TRUNCATE TABLE MOVIES";
break;
case "genres":
cmdText = "TRUNCATE TABLE GENRES";
break;
}
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = cmdText;
cmd.ExecuteNonQuery();
}
conn.Close();
}
}
private void RefreshGenres()
{
tvCategories.Nodes.Clear();
var reader = new Reader();
var genres = reader.GetGenreList();
foreach (string str in genres)
{
tvCategories.Nodes.Add(str);
}
}
private void RefreshMovies(string filter)
{
lvMovies.Items.Clear();
var reader = new Reader();
var movies = reader.GetMovieList(filter);
foreach (ListViewItem item in movies)
{
lvMovies.Items.Add(item);
}
reader.conn.Close();
}
private void tvCategories_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
currentFilter = e.Node.Text;
RefreshMovies(currentFilter);
}
}
I think that the problem here is not the length of your code, but the fact that you are mixing up many different things and that you are not dealing with your events in a consistent way.
These are the main things that I would change:
EraseData: this method opens and uses a DB connection, and this is something that you usually should avoid (changing something in the DB would cause you to modify the UI code), your WinForm code should not know where the data it is exposing come from. Here you'd be better adding an EraseData to your Writer class.
RefreshMovies: it is quite different from RefreshGenres, even if both of these methods do essentially the same thing: they are getting lists of data which are added to some UI controls. RefreshGenres seems ok, but looking at RefreshMovies you immediately see that you are closing a connection that was not opened in this method. Probably you opened it in the Reader class, but that's the place where you should have closed it, too. In fact, it'd be better for conn to be private (remember, UI doesn't have to know whether data come from a DB, a text file, or a user input). Furthermore GetGenreList of Reader returns a list of strings, which is ok, but GetMovieList returns a list of ListViewItem, which is not good because this is something strongly related to your specific implementation of UI. This means that your implementation of Reader could not be used in a WPF or web application. the ListViewItems should be created in RefreshMovies using plain data got from the Reader.

How to check for a specific file and delete it

i am using a C# winform in which i wanted to search for a particular file in a folder and i want to delete it.
How can i do this. i am trying with the below codes.
private void button4_Click(object sender, EventArgs e)
{
string Filename = img_path.Text; // here i have the filename "sample.grf"
if (Directory.GetFiles(#"E:\Debug").Where(x => x.Name == Filename).Any()) // getting error here
{
// i want to search here in above folder and delete the file.. how to do this
System.IO.File.Delete(/dont know how to delte the particular file);
}
}
please help out
This is simply done this way:
File.Delete(Path.Combine(#"E:\Debug", Filename));
No need to check if the file exists first. If it doesn't, File.Delete will simply do nothing.
If you may have any security concern (like a user entering ..\SomethingElse\Important.doc for instance), you need to ensure the field only contains a file name. One way would be:
if (Filename.ToCharArray().Intersect(Path.GetInvalidFileNameChars()).Any())
return;
So your whole function may look lie this:
private void button4_Click(object sender, EventArgs e)
{
string Filename = img_path.Text;
if (string.IsNullOrEmpty(Filename))
return;
if (Filename.ToCharArray().Intersect(Path.GetInvalidFileNameChars()).Any())
return;
File.Delete(Path.Combine(#"E:\Debug", Filename));
}
Also, button4_Click is not a very friendly name to maintain. You may want to consider renaming the button and that function to something meaningful.
If you know the file, just Delete() it:
File.Delete("C:\\mypath\\myfile.txt");
There is no exception thrown for a file that already does not exist, according to MSDN.

Writing a method to serve slightly different scenarios C#

I struggled with what to title this as but hopefully I can explain a little better here. I am trying to write a program that will track an assembly through a 6 station assembly line. At each station, the operator will hit a button (such as station1start, station1stop, station2start, etc) and the button press event will send the timestamp to a database and also update the form visually by moving the traveling id number to the next station. I have this all working for the first couple of stations but I'm wondering if there is a way to use the same method for each station. For example have a method such as
void updateStart(int station_num)
where the station ID would be an argument but otherwise the method could be used for all of the stations. I know that variables in C# cannot be dynamically changed but am curious if there is another way to make this code cleaner. It seems like bad programming to have 6 methods almost identical. Especially if we were to add another 6 stations. See the screenshot of the form and my example code below of the button that the operator would hit when they started at station 2. Any help would be greatly appreciated!
http://i.stack.imgur.com/Ddxww.png
private void Station2Start_Click(object sender, EventArgs e)
{
Station2Label.Text = Station1Label.Text;
Station1Label.Text = "";
Station1Status.Text = "";
Station2Status.Text = "IN PROGRESS";
addTimeToDb(2);
}
The question is somewhat unclear but I believe it is:
I have the following code:
private void Station2Start_Click(object sender, EventArgs e)
{
Station2Label.Text = Station1Label.Text;
Station1Label.Text = "";
Station1Status.Text = "";
Station2Status.Text = "IN PROGRESS";
addTimeToDb(2);
}
private void Station3Start_Click(object sender, EventArgs e)
{
Station3Label.Text = Station2Label.Text;
Station2Label.Text = "";
Station2Status.Text = "";
Station3Status.Text = "IN PROGRESS";
addTimeToDb(2);
}
And so on, repeated many times with minor substitutions. How do I "DRY out" this code? (That is Don't Repeat Yourself.)
When you create the labels and status boxes put them in an array:
private Label[] stationLabels;
private Label[] statusLabels;
...
// in your form initialization after the creation of the labels:
stationLabels = new [] { Station1Label, Station2Label, Station3Label, ...
// and similarly for status labels.
Now write
private void StationClick(int station)
{
stationLabels[station-1].Text = stationLabels[station-2].Text;
... and so on
And then each method becomes
private void Station2Start_Click(object sender, EventArgs e)
{
StationClick(2);
}
private void Station3Start_Click(object sender, EventArgs e)
{
StationClick(3);
}
And so on.

Add textbox text to new string in list each time button is pressed

This is the code:
private void button1_Click(object sender, EventArgs e)
{
List<string> user = new List<string>();
user.Add(usertextBox.Text);
I want it where each time I press the button, whatever is in usertextBox at that point gets added to the list 'user' as a new item, so I can recall the different ones later with [1], [2], [3], etc. I also want it so the user can close the app and all the users will still be saved. I I don't know if C# does this automatically
Even if you can only answer one of my questions that's fine. Thanks!!
In your code you are making List local to Button that means every time you click button new object of List is created, You should create it out side button click method. Try this.
List<string> user = new List<string>();
private void button1_Click(object sender, EventArgs e)
{
user.Add(usertextBox.Text);
You have to define the List out side of the method. C# does not keep the content of the list.
private List<string> user = new List<string>();
private void button1_Click(object sender, EventArgs e)
{
user.Add(usertextBox.Text);
}
for saving the content you could use a database (http://msdn.microsoft.com/en-us/library/bb655884%28v=vs.90%29.aspx) or an xml file (http://www.codeproject.com/Articles/7718/Using-XML-in-C-in-the-simplest-way).
to save the content of the List you could create a new class containing this two methods instead of the list
public List<string> getListContent()
{
//read xml-file
}
public void Add(string t)
{
//write to xml file
}
This will just fine work in single thread applications.

Categories