How to use information from a scope elsewhere - c#

I'd like to use the information gathered from ReadLine() in another code scope.
I've created a menu and I'm using an if-statement.
If I want to use the information gathered in option 1 in the menu, and write it into option 2, how do I go about doing that?
if (selectMenu == 1)
{
Console.WriteLine("What item will you put in the backpack?");
//Console.ReadLine();
string item = Console.ReadLine();
}
else if (selectMenu == 2)
{
}
So basically I want to be able to use item in the else if.

You could declare the variable in the outside scope:
string item = null;
if (selectMenu == 1)
{
Console.WriteLine("What item will you put in the backpack?");
item = Console.ReadLine();
}
else if (selectMenu == 2)
{
}
... you could use the item variable here but it will have its default value of null
if selectMenu was different than 1 because in this example we assign it
only inside the first if.

Related

Else if statement inside for each loop - C#

I have a foreach loop like this where I want the else condition to output: "unit not found" if the quad.ID == searchForQuadcopters isn't found but I get this string value output even when the value is found.
foreach (var quad in allQuadcopters)
{
if (quad.ID == searchForQuadcopter)
{
WriteLine("Value found.");
// write here all the information you want to display.
WriteLine($"ID: {quad.ID}");
WriteLine($"Capacity (kg): {quad.capacityKg}");
WriteLine($"Reach (km): {quad.reachKm}");
WriteLine($"Transponder ID: {quad.transponderID}");
quad.vehicleDeliveryForm();
}
else
{
WriteLine("Unit not found");
}
}
You won't know if the value isn't found unless you iterate over the ENTIRE list first and don't encounter it.
Create a boolean flag to track whether the value was found or not:
bool found = false;
foreach (var quad in allQuadcopters)
{
if (quad.ID == searchForQuadcopter)
{
found = true;
WriteLine("Value found.");
// write here all the information you want to display.
WriteLine($"ID: {quad.ID}");
WriteLine($"Capacity (kg): {quad.capacityKg}");
WriteLine($"Reach (km): {quad.reachKm}");
WriteLine($"Transponder ID: {quad.transponderID}");
quad.vehicleDeliveryForm();
break; // if you don't want to iterate over the rest
}
}
if (!found) {
WriteLine("Unit not found");
}
I want the else condition to output: "unit not found" if the quad.ID == searchForQuadcopters isn't found
Then you don't want this loop. Your code loops over all items, and if allQuadcopters contains Ids 1, 2 and 3 and you're looking for 2, it will print "Unit not found" for Ids 1 and 3. You could break; out of the loop in your if(), but then the else will still be hit for 1.
You want to leverage Linq here:
var quad = allQuadcopters.FirstOrDefault(q => q.ID == searchForQuadcopters);
if (quad == null)
{
WriteLine("Unit not found");
}
else
{
WriteLine("Value found.");
// write here all the information you want to display.
WriteLine($"ID: {quad.ID}");
}

How can I access control created within if-statement from outside if-statement in C# WinForms?

I'm loading music playlist from disk to C# ListView control. I'm using ListViewGroups to separate albums, and there can be several albums in playlist.
Playlists are saved in following text format: (not the greatest way, I know, but works for this example)
|album|name of album
track 1 fsdfsfasf.mp3
track 2 fdsgfgfdhhh.mp3
track 3 gfdgsdgsdfgs.mp3
When I'm loading playlist to ListView, I test if string "|album|" is found from the beginning of line, and use that line for group header text. Code sample below:
using (StreamReader reader = File.OpenText("playlist.txt"))
{
while (reader.Peek() >= 0)
{
result = reader.ReadLine();
if (result.Substring(0, 7) == "|album|")
{
ListViewGroup group = new ListViewGroup();
group.Header = result.Substring(7);
lstPlaylist.Groups.Add(group); // lstPlaylist is existing ListView control for playlist
}
else
{
ListViewItem item = new ListViewItem(result, 0, group);
lstPlaylist.Items.Add(item);
}
}
}
If "|album|" string is found, then I create new ListViewGroup. But that group is inaccessible inside else-statement (I can't assign item to group), because it's out of scope. How can I create new ListViewGroup inside if-statement and use it outside that if-statement?
You need to declare the variable outside the if statement so that it is available in the else clause. You also need to handle the case when a track is found before an album, unless you have already validated the source file.
using (StreamReader reader = File.OpenText("playlist.txt"))
{
ListViewGroup group = null;
while (reader.Peek() >= 0)
{
result = reader.ReadLine();
if (result.Substring(0, 7) == "|album|")
{
group = new ListViewGroup();
group.Header = result.Substring(7);
lstPlaylist.Groups.Add(group); // lstPlaylist is existing ListView control for playlist
}
else
{
if (group != null)
{
ListViewItem item = new ListViewItem(result, 0, group);
lstPlaylist.Items.Add(item);
}
else
{
// you are trying to add a track before any group has been created.
// handle this error condition
}
}
}
}
You have to first declare the variable outside the if statement and then give it whatever values inside the if statement. Or outside if you want the same value in both the if and else.
Basically what is happening is that the variable is never being made if you go to the else portion of your code because it is created and initialized in the if portion.
Good Luck!
Looking at your logic, you need to initialize ListViewGroup in either case. If you find the word "|album|" then you also assign a property value. So an easy fix is to move the variable up to increase it's scope:
ListViewGroup group = new ListViewGroup();//move to here
if (result.Substring(0, 7) == "|album|")
{
group.Header = result.Substring(7);
lstPlaylist.Groups.Add(group); // lstPlaylist is existing ListView control for playlist
}
else
{
ListViewItem item = new ListViewItem(result, 0, group);//now group is initialized here as well
lstPlaylist.Items.Add(item);
}

Switch statement inside a foreach loop - not getting expected results

So I am trying to loop though items that are in a listbox in my application. The list box will allow you to select multiple items to which I have a method tied to each item in the listbox. I have a counter variable incremented each time the loop works.When I use the foreach loop with the switch statement below, it does the first item correct, but then loops through the same item again. I know I am missing something as it is supposed to go to the next item in the listbox and not the same item.
string reportname = lstbxReports.SelectedValue.ToString();
int i = 0;
foreach (var report in reportname)
{
switch (reportname)
{
case "Overview":
{
if (i < 1)
{
PrintOverview(filename);
}
else if (i >= 1)
{
PrintOverviewAppend(filename);
}
break;
}
case "Sources":
{
if (i < 1)
{
PrintSource(filename);
}
else if (i >= 1)
{
PrintSourceAppend(filename);
}
break;
}
}
i++
Any thoughts or suggestions on how I can get the foreach loop to go to the next item in the selected listbox?
Also, this is just a snippet as I have about 11 case items to loop through.
You probably want to switch on report, not reportname.
foreach(string item in listBox.Items)
{
}
?
Depends on how you setup the data source for the listbox though (I'm assuming this is WinForm?). If you created it by adding .Items or using the designer then this will work. However if you've used .DataSource then it wont work.
I'd personally have a
List<string> list = SomeMethodWhereIMakeTheList();
and set that to:
listbox.DataSource = list;
then I wouldn't even have to touch the ListBox to mess with the contents:
list.ForEach(...)
Don't do the print logic in a foreach. Split out the data then print such this (note I changed the name of reportname to reportnames to signify a list of items)
string reportnames = lstbxReports.SelectedValue.ToString();
var firstReport = reportnames.First(); // No error checking here, would use FirstOrDefault with null checks.
if (firstReport == "OverView")
PrintOverview(filename);
else
PrintSource(filename);
// Now print out the rest
reportnames.Skip(1)
.ToList()
.ForEach(rp =>
{
if (rp == "OverView")
PrintOverviewAppend(filename);
else
PrintSourceAppend(filename);
});

Check List Box before Adding New Item

I am trying to check that an item doesn't already exist in a list box before I add the new item.
if (TeamNameTextBox.Text != "")
{
if (TeamNameListBox.Items.FindByValue(TeamNameListBox.Text) == null)
{
TeamNameListBox.Items.Add(TeamNameTextBox.Text);
TeamNameTextBox.Text = "";
int teamCountUpdate = TeamNameListBox.Items.Count;
if (teamCountUpdate == 1)
{
TeamCount.Text = teamCountUpdate.ToString() + " Team";
}
else
{
TeamCount.Text = teamCountUpdate.ToString() + " Teams";
}
}
else
{
AddTeamSeasonError.Text = "This team has already been added";
}
}
else
{
AddTeamSeasonError.Text = "Please select a team";
}
I have got it to check if the text box is blank, but I need to check that the item a user is trying to add is not already in the the list box.
I have tried the line:
if (TeamNameListBox.Items.FindByValue(TeamNameListBox.Text) == null)
But that doesn't work, any suggestions on how I can do the check?
Use this:
if (!TeamNameListBox.Items.Contains(TeamNameTextBox.Text))
TeamNameListBox.Items.Add(TeamNameTextBox.Text);
think you should at least try to use TeamNameTextBox instead of TeamNameListBox as argument
if (TeamNameListBox.Items.FindByValue(TeamNameTextBox.Text) == null)
I suppose you mean
// search if the textbox value is found in the list. this comment shouldn't be part of the code
if (TeamNameListBox.Items.FindByValue(TeamNameTextBox.Text) == null)
instead of
if (TeamNameListBox.Items.FindByValue(TeamNameListBox.Text) == null) // code from question
EDIT: There is no need to put the name of the type of the control next to the variable.
i.e. instead of TeamNameListBox, use teamNames. And, instead of TeamNameTextBox, use teamName.

Best way to check if a drop down list contains a value?

When the user navigates to a new page, this ddl's selected index is determined by a cookie, but if the ddl doesn't contain that cookie's value, then I'd like it to be set the 0. What method would I use for the ddl? Is a loop the best way, or is there a simply if statement I can perform?
This is what I've attempted, but it doesn't return a bool.
if ( !ddlCustomerNumber.Items.FindByText( GetCustomerNumberCookie().ToString() ) )
ddlCustomerNumber.SelectedIndex = 0;
There are two methods that come to mind:
You could use Contains like so:
if (ddlCustomerNumber.Items.Contains(new
ListItem(GetCustomerNumberCookie().ToString())))
{
// ... code here
}
or modifying your current strategy:
if (ddlCustomerNumber.Items.FindByText(
GetCustomerNumberCookie().ToString()) != null)
{
// ... code here
}
EDIT: There's also a DropDownList.Items.FindByValue that works the same way as FindByText, except it searches based on values instead.
That will return an item. Simply change to:
if (ddlCustomerNumber.Items.FindByText( GetCustomerNumberCookie().ToString()) != null)
ddlCustomerNumber.SelectedIndex = 0;
If 0 is your default value, you can just use a simple assignment:
ddlCustomerNumber.SelectedValue = GetCustomerNumberCookie().ToString();
This automatically selects the proper list item, if the DDL contains the value of the cookie. If it doesn't contain it, this call won't change the selection, so it stays at the default selection. If the latter one is the same as value 0, then it's the perfect solution for you.
I use this mechanism quite a lot and find it very handy.
What about this:
ListItem match = ddlCustomerNumber.Items.FindByText(
GetCustomerNumberCookie().ToString());
if (match == null)
ddlCustomerNumber.SelectedIndex = 0;
//else
// match.Selected = true; // you'll probably select that cookie value
On C# this works:
if (DDLAlmacen.Items.Count > 0)
{
if (DDLAlmacen.Items.FindByValue("AlmacenDefectoAndes").Value == "AlmacenDefectoAndes")
{
DDLAlmacen.SelectedValue = "AlmacenDefectoAndes";
}
}
Update:
Translating the code above to Visual Basic doesn't work. It throws "System.NullReferenceException: Object reference not set to an instance of an object.."
So. for this to work on Visual Basic, I had to change the code like this:
If DDLAlmacen.Items.Count > 0 Then
If DDLAlmacen.Items.Contains(New ListItem("AlmacenDefectoAndes")) Then
DDLAlmacen.SelectedValue = "AlmacenDefectoAndes"
End If
End If
ListItem item = ddlComputedliat1.Items.FindByText("Amt D");
if (item == null) {
ddlComputedliat1.Items.Insert(1, lblnewamountamt.Text);
}
You could try checking to see if this method returns a null:
if (ddlCustomerNumber.Items.FindByText(GetCustomerNumberCookie().ToString()) != null)
ddlCustomerNumber.SelectedIndex = 0;
//you can use the ? operator instead of if
ddlCustomerNumber.SelectedValue = ddlType.Items.FindByValue(GetCustomerNumberCookie().ToString()) != null ? GetCustomerNumberCookie().ToString() : "0";
If the function return Nothing, you can try this below
if (ddlCustomerNumber.Items.FindByText(
GetCustomerNumberCookie().ToString()) != Nothing)
{
...
}
Sometimes the value needs to be trimmed of whitespace or it won't be matched, in such case this additional step can be used (source):
if(((DropDownList) myControl1).Items.Cast<ListItem>().Select(i => i.Value.Trim() == ctrl.value.Trim()).FirstOrDefault() != null){}

Categories