I am displaying menu in the console based application using C#. I want that if user press enter key then it should display same menu. Application should not break. I am new to C#
If anyone has idea please share it. It will be helpful to me.
Below is the code.
public static void HospitalMenu()
{
string answer = "";
do
{
Console.Clear();
Console.WriteLine("=============Hospital Management System===================");
Console.WriteLine("1...............Add Patient Information");
Console.WriteLine("2...............Modify Patient Information");
Console.WriteLine("3...............Add Patient Treatment Information");
Console.WriteLine("4...............View Patient History");
Console.WriteLine("5...............Search Patient Info");
Console.WriteLine("6...............Generate Lab Report");
Console.WriteLine("7...............Generate Medical Bills");
Console.WriteLine("8...............Exit");
Console.WriteLine("Select option (between 1 to 8)");
int option = Convert.ToInt32(Console.ReadLine());
switch (option)
{
case 1:
Patient.InsertPatient();
break;
case 2:
Patient.UpdatePatient();
break;
case 3:
PatientTreatment();
break;
case 4:
ViewMenu();
break;
case 5:
SearchMenu();
break;
case 6:
LabMenu();
break;
case 7:
BillMenu();
break;
default:
Environment.Exit(0);
break;
}
Console.WriteLine("Do you want to continue ? (Enter y if yes)");
answer = Console.ReadLine();
} while (answer == "y" || answer == "Y");
}
Thanks in advance.
I'll suggest some changes in your code.
Let's create an Interface that you'll be a contract responsible to show and handle inputs
IMenuHandler.cs
public interface IMenuHandler<TInput>
{
void Show( Action stopApplicationHandler, IMenuHandler<TInput> callerMenu=null);
void HandleInput(TInput input, Action stopApplication, IMenuHandler<TInput> callerMenu);
}
Then let's create your menus.. .
As an example you'll create two, you should modify it for your needs.
MainMenu.cs
public class MainMenu:IMenuHandler<ConsoleKeyInfo>
{
public void Show(Action stopApplicationHandler, IMenuHandler<ConsoleKeyInfo> callerMenu = null)
{
Console.Clear();
Console.WriteLine("=============Hospital Management System===================");
Console.WriteLine("1...............Add Patient Information");
Console.WriteLine("2...............Modify Patient Information");
Console.WriteLine("3...............Add Patient Treatment Information");
Console.WriteLine("4...............View Patient History");
Console.WriteLine("5...............Search Patient Info");
Console.WriteLine("6...............Generate Lab Report");
Console.WriteLine("7...............Generate Medical Bills");
Console.WriteLine("8...............Exit");
Console.WriteLine("Select option (between 1 to 8)");
HandleInput(Console.ReadKey(), stopApplicationHandler, callerMenu ?? this);
}
public void HandleInput(ConsoleKeyInfo input, Action stopApplication, IMenuHandler<ConsoleKeyInfo> callerMenu)
{
switch (input.Key)
{
case ConsoleKey.D1:
new HelpMenu().Show(stopApplication, callerMenu);
break;
case ConsoleKey.D8:
stopApplication.Invoke();
break;
default:
Show(stopApplication, this);
break;
}
}
}
HelpMenu.cs
public class HelpMenu:IMenuHandler<ConsoleKeyInfo>
{
public void Show(Action stopApplicationHandler, IMenuHandler<ConsoleKeyInfo> callerMenu = null)
{
Console.Clear();
Console.WriteLine("Help Menu Example...");
Console.WriteLine("1...............Go back");
Console.WriteLine("2...............Exit");
HandleInput(Console.ReadKey(), stopApplicationHandler, callerMenu );
}
public void HandleInput(ConsoleKeyInfo input, Action stopApplication, IMenuHandler<ConsoleKeyInfo> callerMenu)
{
Console.WriteLine("Help menu handler...");
switch (input.Key)
{
case ConsoleKey.D1:
callerMenu.Show(stopApplication, this);
break;
case ConsoleKey.D2:
stopApplication.Invoke();
break;
default:
Show(stopApplication, callerMenu);
break;
}
}
}
Now we are going to create an wrapper for your application.
Application.cs
public class Application
{
public delegate void OnStopApplicationRequestHandler();
public event OnStopApplicationRequestHandler StopApplicationRequest;
private readonly CancellationTokenSource _cancellationTokenSource;
public Application(CancellationToken? cancellationToken=null, OnStopApplicationRequestHandler? stopApplicationRequestHandler=null)
{
_cancellationTokenSource = cancellationToken != null
? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken.Value)
: new CancellationTokenSource();
StopApplicationRequest += stopApplicationRequestHandler ?? ConfigureDefaultStopApplicationRequestHandler();
}
private OnStopApplicationRequestHandler ConfigureDefaultStopApplicationRequestHandler()
=> () =>
{
Console.WriteLine("Stopping application...");
_cancellationTokenSource.Cancel();
};
public void Run()
{
try
{
while (!_cancellationTokenSource.Token.IsCancellationRequested)
new MainMenu().Show(Stop);
Console.WriteLine("Program has been stopped");
}
//.... You should handle other custom exceptions here
catch (Exception ex)
{
// I'll assume that you will stop your application case it hits this unhandled exception
Console.WriteLine(ex);
Stop();
}
}
private void Stop()
{
StopApplicationRequest?.Invoke();
}
}
Note that this class has an event that will be responsible to handle the application exits.
You should modify it for your needs.
Last but not least
Call your application wrapper in your Program.cs
internal class Program
{
static void Main(string[] args)
{
new Application().Run();
}
}
PS: Don't forget the correct usings....
Hope this helps
Related
I'm writing a simple text adventure, and would like to have a main menu, which can be accessed at any time, while any other method is running just by typing "menu" in the console
Here's some code that I wrote (sorry, if it's not very good, I'm only starting to learn), but in this example the menu can be accessed only once at the beginning, while I'd like it to run anytime i type "menu", no matter which part of the program is currently running
So, is there any simple and efficient way to check for certain input ("menu" in this case) without copy pasting menu call method everywhere?
Any help would be appreciated, thank you in advance
(This is my previous attempt, which doesn't work, my new approach is in UPDATE1)
class Program
{
static int menuSwitch = 0;
static void Main(string[] args)
{
Console.WriteLine("Welcome to the test program");
string menu = "menu";
string trymenu = Console.ReadLine();
do
{
Console.WriteLine("Main menu");
Console.WriteLine("1.Entry1 \n2.Entry2");
Int32.TryParse(Console.ReadLine(), out menuSwitch);
switch (menuSwitch)
{
case 1:
Console.WriteLine("Entry1");
break;
case 2:
Console.WriteLine("Entry2");
break;
default:
Console.WriteLine("Exiting menu");
break;
}
break;
} while (trymenu == menu);
{
Start();
Continue();
End();
}
}
}
UPDATE1
So, I've done some tinkering and managed to get it working as intended, keeping in mind Alejandro's advice, however as I expected, now I have to call the Menu method after every step (console messages in this case) of another (Start) method
I've been wondering if there is any workaround for this, or any other efficient method to check if there is a "menu" input, as it seems kind of excessive and tedious to work with the way it is now
class Program
{
static void Main(string[] args)
{
Start();
}
static void Menu()
{
int menuSwitch = 0;
string menu = "menu";
string trymenu = Console.ReadLine();
if (trymenu == menu)
{
Console.WriteLine("Main menu");
Console.WriteLine("1.Entry1 \n2.Entry2");
Int32.TryParse(Console.ReadLine(), out menuSwitch);
switch (menuSwitch)
{
case 1:
Console.WriteLine("Entry1");
break;
case 2:
Console.WriteLine("Entry2");
break;
default:
Console.WriteLine("Exiting menu");
break;
}
}
}
static void Start()
{
Console.WriteLine("Welcome to the test program");
Menu();
Console.WriteLine("Type 'menu' to access the main menu");
Menu();
Console.WriteLine("Message1");
Menu();
Console.WriteLine("Message2");
Menu();
Console.WriteLine("Message3");
Menu();
}
}
The simplest way would probably be to move the common code to a method. You might however want to model your game as a state machine.
This allows you to separate most of the content from the game logic. This is very useful since it allows you to store the content in some file that can be loaded by the game engine. A very simple state could look something like this:
public interface IState
{
string Description { get; }
IEnumerable<ITransition> Transitions { get; }
void OnActivated(IState from);
}
public interface ITransition
{
string Command { get; }
IState TargetState { get; }
}
In this model commands are modeled as transitions between states. There are several ways to have transitions that are global:
Make a base class that contains global transitions that all states should have
Add the global states explicitly when creating each state (probably with some helper method)
Built the global transitions directly into the main game loop
An example of the last alternative could be something like this:
public class Game
{
private readonly IState initialState;
private readonly IEnumerable<ITransition> globalCommands;
private readonly IState exitState;
public Game(IState initialState, IEnumerable<ITransition> globalCommands, IState exitState)
{
this.initialState = initialState;
this.globalCommands = globalCommands;
this.exitState = exitState;
}
private IEnumerable<ITransition> GetTransitions(IState state) => state.Transitions.Concat(globalCommands);
public void Loop()
{
var currentState = initialState;
while (currentState != exitState)
{
Console.WriteLine(currentState.Description);
var transitions = GetTransitions(currentState).ToList();
foreach (var transition in transitions)
{
Console.WriteLine(transition.Command);
}
ITransition nextTransition;
do
{
var command = Console.ReadLine();
nextTransition = transitions.FirstOrDefault(t => t.Command.Equals(command));
} while (nextTransition == null);
nextTransition.TargetState.OnActivated(currentState);
currentState = nextTransition.TargetState;
}
}
}
One complexity with this is that you probably want to return to whatever state you left when you exit the menu. One way to do this could be to save the state you entered the menu from in a "exit" transition:
public class MenuState : IState
{
public string Description { get; }
IEnumerable<ITransition> IState.Transitions => Transitions.Concat(new[] {exit});
public List<ITransition> Transitions { get; } = new List<ITransition>();
private Transition exit;
public virtual void OnActivated(IState from) => exit = new Transition("exit", from);
public MenuState(string description) => Description = description;
}
So in this code block from my console application, when ran, should move the 'X' in Class02 up and down when you hit the respective arrow keys but it doesn't, it just stays in place:
class Program
{
static void Main(string[] args)
{
Class01.Function01();
}
}
class Class01
{
public int num01 = 5;
public int num02 = 5;
public static void Function01()
{
while (true)
{
Class02.Function02();
}
}
}
class Class02
{
public static void Function02()
{
var c1 = new Class01();
Console.SetCursorPosition(c1.num02, c1.num01);
Console.Write("X");
ConsoleKeyInfo keyInfo;
keyInfo = Console.ReadKey(true);
switch (keyInfo.Key)
{
case ConsoleKey.UpArrow:
c1.num01--;
break;
case ConsoleKey.DownArrow:
c1.num01++;
break;
}
}
}
I know what's wrong here, the int in Class01 is not being changed in class02. therefore the Cursor Position is still set as 5 5 writing the 'X' in the same place every key stroke.
So, how does one change the value of int num01 in Class02?
Thanks for any help with this.
You are always creating a new instance of Class01 in the static method Class02.Function02, therefore the value is always it's default value 5. You could make the numbers static too or you could hold a static instance variable of Class01 in Class02, for example:
class Class02
{
private Class01 c1 = New Class01();
public static void Function02()
{
Console.SetCursorPosition(c1.num02, c1.num01);
Console.Write("X");
ConsoleKeyInfo keyInfo;
keyInfo = Console.ReadKey(true);
switch (keyInfo.Key)
{
case ConsoleKey.UpArrow:
c1.num01--;
break;
case ConsoleKey.DownArrow:
c1.num01++;
break;
}
}
}
another option is to pass the instance of Class01 to the method:
public static void Function02(Class01 c1)
{
Console.SetCursorPosition(c1.num02, c1.num01);
Console.Write("X");
ConsoleKeyInfo keyInfo;
keyInfo = Console.ReadKey(true);
switch (keyInfo.Key)
{
case ConsoleKey.UpArrow:
c1.num01--;
break;
case ConsoleKey.DownArrow:
c1.num01++;
break;
}
}
then you call it in this way:
Class01 c1 = new Class01();
while (true)
{
Class02.Function02(c1);
}
If the calling method Function01 would not be static you could pass this.
The error is, that in every single call you create a new instance of class01 with the initial values in it.
I created a menu with sub menus in console. Everything works fine but I wonder if it is not possible to improve the structure of my program. To simplify it and make it more generic.
class MainClass
{
public static void Main(string[] args)
{
MainMenu();
}
public static void MainMenu()
{
Console.WriteLine("Main Menu");
Console.WriteLine("--------------------");
Console.WriteLine("[1] Show activities");
Console.WriteLine("[2] Show teachers");
Console.WriteLine("[3] Show students");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
string choice = Console.ReadLine();
int number;
bool result = Int32.TryParse(choice, out number);
if (result)
{
Console.Clear();
SubMenu(number);
}
else
{
Console.WriteLine("Incorrect choice");
}
}
public static void SubMenu(int mainMenuChoice)
{
switch (mainMenuChoice)
{
case 1:
Console.WriteLine("Activities");
Console.WriteLine("[1] Show all activities");
Console.WriteLine("[2] Find a activity by his code");
Console.WriteLine("[3] Return Main Menu");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
break;
case 2:
Console.WriteLine("Teachers");
Console.WriteLine("[1] Show all teachers");
Console.WriteLine("[2] Find a teacher by his matricule");
Console.WriteLine("[3] Return Main Menu");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
break;
case 3:
Console.WriteLine("Students");
Console.WriteLine("[1] Show all students");
Console.WriteLine("[2] Find a student by his matricule");
Console.WriteLine("[3] Return Main Menu");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
break;
case 4:
Environment.Exit(0);
break;
}
string choice = Console.ReadLine();
int number;
bool result = Int32.TryParse(choice, out number);
if (result)
{
Action(mainMenuChoice, number);
}
else
{
Console.WriteLine("Incorrect choice");
}
}
public static void Action(int menu, int choice)
{
switch (menu)
{
case 1:
switch (choice)
{
case 1:
// Do Stuff
break;
case 2:
// Do Stuff
break;
case 3:
Console.Clear();
MainMenu();
break;
case 4:
Environment.Exit(0);
break;
}
break;
case 2:
switch (choice)
{
case 1:
// Do Stuff
break;
case 2:
// Do Stuff
break;
case 3:
Console.Clear();
MainMenu();
break;
case 4:
Environment.Exit(0);
break;
}
break;
case 3:
switch (choice)
{
case 1:
// Do Stuff
break;
case 2:
// Do Stuff
break;
case 3:
Console.Clear();
MainMenu();
break;
case 4:
Environment.Exit(0);
break;
}
break;
}
}
}
Currently if I have to add a sub menu, I have to add a line to the MainMenu() function, I must add a case in the SubMenu() function and as many as there are choices for this menu in Action().
For only one sub menu it's ok but if I have to add a dozen it quickly becomes unmanageable.
I should probably go through one or more classes but I'm lost on the structure.
I made something quickly to demonstrate one approach to the problem. I commented most of the code, but ask if anything is unclear. The main advantage to me is that you can declare your menus in one place as objects. In my code I have done this explicitly in the Main method, but you could easily write a factory method to generate menus for you.
class Program
{
//represents a line/option in a menu
class MenuItem
{
// displayed in the menu
public string Text { get; set; }
//is there a sub menu
public bool HasSubMenu { get; set; }
// if there's a submenu, what's its id
public int? SubMenuId { get; set; }
//if there isn't a sub menu, what should we do
public Action Action { get; set; }
}
//represents one menu i.e. a collection of options
class Menu
{
public Menu()
{
MenuItems = new List<MenuItem>();
}
public int MenuId { get; set; }
public List<MenuItem> MenuItems { get; set; }
public string Title { get; set; }
public void PrintToConsole()
{
foreach (MenuItem item in MenuItems)
{
Console.WriteLine(MenuItems.IndexOf(item) + " : " + item.Text);
}
}
}
//represents all the menus
class MenuCollection
{
public MenuCollection()
{
Menus = new List<Menu>();
}
public List<Menu> Menus { get; set; }
public void ShowMenu(int id)
{
//get the menu we want to display and call its PrintToConsole method
var currentMenu = Menus.Where(m => m.MenuId == id).Single();
currentMenu.PrintToConsole();
//wait for user input
string choice = Console.ReadLine();
int choiceIndex;
//once we have the users selection make sure its an integer and in range of our menu options
//if not then show an error message and re-display the menu
if (!int.TryParse(choice, out choiceIndex) || currentMenu.MenuItems.Count < choiceIndex || choiceIndex < 0)
{
Console.Clear();
Console.WriteLine("Invalid selection - try again");
ShowMenu(id);
}
else
{
// if the selection is good, then retrieve the corresponding menu item
var menuItemSelected = currentMenu.MenuItems[choiceIndex];
// if there's a sub menu then display it
if (menuItemSelected.HasSubMenu)
{
Console.Clear();
ShowMenu(menuItemSelected.SubMenuId.Value);
}
// otherwise perform whatever action we need
else
{
menuItemSelected.Action();
}
}
}
}
static void Main(string[] args)
{
// build a collection of menus
// can have as deep a structure as you like
// give each menu a unique integer MenuId
// link to other menus by setting HasSubMenu to true, and the SubMenuId to the MenuId of the menu you wish to link to
// or, set HasSubMenu to false, and have an Action performed when the menuitem is selected
MenuCollection collection = new MenuCollection()
{
Menus =
{
new Menu()
{
MenuId = 1,
MenuItems =
{
new MenuItem()
{
Text = "Go to sub menu",
HasSubMenu = true,
SubMenuId = 2
},
new MenuItem()
{
Text = "Print Action",
HasSubMenu = false,
Action = () =>
{
Console.WriteLine("I printed from an action");
}
}
}
},
new Menu()
{
MenuId = 2,
MenuItems =
{
new MenuItem()
{
Text = "Sub menu option 1",
HasSubMenu = false,
Action = () =>
{
Console.WriteLine("Printed from a sub menu");
}
},
new MenuItem()
{
Text = "Back to the top menu",
HasSubMenu = true,
SubMenuId = 1
}
}
}
}
};
collection.ShowMenu(1);
Console.ReadLine();
}
}
I have been making a lot of small CLI tools recently, I only fleshed out Activities, but here's an example of the approach I generally like to take for lots of branching menus/logic:
class Program
{
static T GetChoice<T>(List<Tuple<string, T>> choices)
{
var i = 1;
choices.ForEach(x => Console.WriteLine($"[{i++}]: {x.Item1}"));
var choiceIndex = int.Parse(Console.ReadLine());
return choices[choiceIndex - 1].Item2;
}
static void Main(string[] args)
{
Console.WriteLine("Main Menu: ");
var choices = new List<Tuple<string, Action>>()
{
new Tuple<string, Action>("Show Activities", ShowActivities),
new Tuple<string, Action>("Show Teachers", ShowTeachers),
new Tuple<string, Action>("Show Students", ShowStudents),
new Tuple<string, Action>("Exit", Exit),
};
GetChoice(choices)();
}
static void ShowActivities()
{
Console.WriteLine("Activities: ");
var choices = new List<Tuple<string, Action>>()
{
new Tuple<string, Action>("Show all activities", ShowAllActivities),
new Tuple<string, Action>("Find activity by code", FindActivityByCode),
new Tuple<string, Action>("Return to main menu", () => { Main(null); }),
new Tuple<string, Action>("Exit the program", Exit),
};
GetChoice(choices)();
}
static void ShowTeachers()
{
Console.WriteLine("Teachers: ");
var choices = new List<Tuple<string, Action>>();
}
static void ShowStudents()
{
Console.WriteLine("Students: ");
var choices = new List<Tuple<string, Action>>();
}
static void ShowAllActivities()
{
//Do stuff
}
static void FindActivityByCode()
{
//Do stuff
}
static void ReturnToMainMenu()
{
//Do stuff
}
static void Exit()
{
Environment.Exit(0);
}
}
I would like to access list (in my program named "section") inside a method(menu choose). I tried 3 ways:
public static void dataBase()
{
List<float> section = new List<float>();
}
// 1st try
// List<float> section = new List<float>();
//
public static void mainMenu()
{
Console.Clear();
Console.WriteLine("Trans->Connector->\n");
Console.WriteLine("Add: \n1. Section \n2. Wled \n3. Regenerator");
menuChoose();
}
public static void menuChoose()
{
var key = Console.ReadKey();
switch (key.Key)
{
case ConsoleKey.D1:
case ConsoleKey.NumPad1:
Console.Clear();
Console.WriteLine("Give lenght:");
float result;
float.TryParse(Console.ReadLine(), out result);
dataBase.section.Add();
section.Add(result);
break;
case ConsoleKey.D2:
Console.WriteLine("2");
break;
case ConsoleKey.D3:
Console.WriteLine("3");
break;
default:
Console.WriteLine("default");
break;
}
}
static void Main(string[] args)
{
int WeldCount;
int ConnectroCount;
//3rd try
// List<float> section = new List<float>();
//
mainMenu();
}
Thank you for your time!
You can't access a member in the local scope of your function outside it. You might want to think about making it a private instance variable inside your class that you will then be able to access from any method declared that belongs to this class, something along these lines:
public class MyClass
{
// this field is accessible from any method declared within this class
private List<Float> section;
public MyClass()
{
section = new List<Float>();
}
private void someMethod()
{
section.Add(2.2);
Console.WriteLine(section[0]); // example
}
}
Well you can make it class level variable (like in your 1st try) and make it static.
However you should use return value from your menuChoose() method. Having all code depend on single static list instance is not ideal.
public static List<float> menuChoose()
{
List<float> selection = new List<float>();
var key = Console.ReadKey();
switch (key.Key)
{
case ConsoleKey.D1:
case ConsoleKey.NumPad1:
Console.Clear();
Console.WriteLine("Give lenght:");
float result;
float.TryParse(Console.ReadLine(), out result);
selection.Add(result);
break;
case ConsoleKey.D2:
Console.WriteLine("2");
break;
case ConsoleKey.D3:
Console.WriteLine("3");
break;
default:
Console.WriteLine("default");
break;
}
return selection;
}
You can to it, if you would implement something like this:
public static class DataBase
{
public static List<float> Section { get; set; }
static DataBase()
{
Section = new List<float>();
}
}
here how to use e.g. in your switch statement:
case ConsoleKey.NumPad1:
Console.Clear();
Console.WriteLine("Give lenght:");
float result;
float.TryParse(Console.ReadLine(), out result);
DataBase.Section.Add(result);
break;
I didn't get what you try to achieve by dataBase.section.Add(); so I removed it in my example.
I could not use any of your answers so I did this in my way(much worse than yours, for sure)
public class Program
{
public int WeldCount;
public int ConnectroCount;
public List<float> section = new List<float>();
//public List<> TrackElements = new List<>();
public Program()
{
section.Add(0);
}
public void showResults()
{
float allSections = 0;
foreach (float item in section)
{
allSections += item;
}
Console.Clear();
Console.WriteLine("c1 {0}, c2 {1}, c3{2}", WeldCount,ConnectroCount,allSections);
Console.ReadKey();
}
public void finalConstruction()
{
}
public static void mainMenu()
{
Console.Clear();
Console.WriteLine("\n");
Console.WriteLine("Add: \n1. Section \n2. Weld \n3. Regenerator\n4. Show results");
}
public void menuChoose()
{
var key = Console.ReadKey();
switch (key.Key)
{
case ConsoleKey.D1:
case ConsoleKey.NumPad1:
Console.Clear();
Console.WriteLine("Give lenght:");
float result;
float.TryParse(Console.ReadLine(), out result);
section.Add(result);
mainMenu();
menuChoose();
break;
case ConsoleKey.D2:
WeldCount++;
mainMenu();
menuChoose();
break;
case ConsoleKey.D3:
ConnectroCount++;
mainMenu();
menuChoose();
break;
case ConsoleKey.D4:
showResults();
mainMenu();
menuChoose();
break;
default:
Console.WriteLine("wtf did just happend");
break;
}
}
static void Main(string[] args)
{
Program program = new Program();
mainMenu();
program.menuChoose();
}
}
}
I am asking the user of my app per the XNA GamerService dialog-box, if he really wants to delete a specific product.
And if he presses yes, this will take action:
private void OnMessageBoxAction(IAsyncResult ar)
{
int? selectedButton = Guide.EndShowMessageBox(ar);
switch (selectedButton)
{
case 0:
WebClient cweight = new WebClient();
cweight.Encoding = System.Text.Encoding.GetEncoding("ISO-8859-1");
cweight.Credentials = new NetworkCredential(op.username, op.userpass);
cweight.DownloadStringCompleted += new DownloadStringCompletedEventHandler(deleted);
cweight.DownloadStringAsync(new Uri("http://mydomain.com"));
break;
case 1:
Debug.WriteLine("1 pressed");
break;
default:
Debug.WriteLine("default pressed");
break;
}
}
and when the download completes, I invoke the login method:
private void deleted(object sender, DownloadStringCompletedEventArgs e)
{
Debug.WriteLine("\n[#] deleted");
if (e.Error != null)
{
Debug.WriteLine("Delete problem");
}
Debug.WriteLine("Delete successful");
login(null, null);
}
later on at login I get the invalid cross-thread access at globalprogress.Visibility = System.Windows.Visibility.Visible; and I am pretty sure, that that error would occur through the whole login method.
Handy class:
public class SmartDispatcher
{
public static void BeginInvoke(Action action)
{
if (Deployment.Current.Dispatcher.CheckAccess()
|| DesignerProperties.IsInDesignTool)
{
action();
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(action);
}
}
}