Porting console based ui to a GUI one? - user-interface

As most of you experienced, developing a console app is as easy as:
void mainloop(){
while (1){
giveInstructions();
getInput();
if (!process()) break;
printOutput();
}
}
int main(){
mainloop();
return 0;
}
However, in GUI it becomes an issue.
We can still giveInstructions(), process(), and printOutput(), but getInput() wouldn't work because it relies on an event, usually button click or key down.
How can I port a console app to a gui app with minimum code changes? (preferably do not change the main method, and as little change to the mainloop function as possible)
Note: I'm not too comfortable with threading yet.

Since there is no specific language given, I will show an example in C# where you would be able to use the same code as the console app with a simple GUI.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//using form-editor, double-click buttons or use the following
btnInput.Click += new EventHandler(btnInput_Click);
btnContinue.Click += new EventHandler(btnContinue_Click);
giveInstructions();
}
private void giveInstructions()
{
txtInfo.Text = "";
txtInput.Text = "";
//display instructions to multi-line textbox
}
private void btnInput_Click(object sender, EventArgs e)
{
//or you can just add another button for exit.
if (txtInput.Text == "expected value for exit")
{
Application.Exit();
}
else
{
getInput();
}
}
private void getInput()
{
string strInput = txtInput.Text;
//do stuff
printOutput();
}
private void printOutput()
{
//display output to multi-line textbox
}
private void btnContinue_Click(object sender, EventArgs e)
{
giveInstructions();
}
}

Related

GTK# - PropertyNotifyEvent doesn't seem to work

I try to make my app to react on property change of a widget, but the signal PropertyNotifyEvent is never invoke.
For test purpose i make a very simple application containing a label and a button. Pressing the button change text property of label but the PropertyNotifyEvent isn't responding.
using System;
using Gtk;
public partial class MainWindow : Gtk.Window
{
public MainWindow() : base(Gtk.WindowType.Toplevel)
{
Build();
label1.AddEvents((int)(Gdk.EventMask.PropertyChangeMask));
}
protected void OnDeleteEvent(object sender, DeleteEventArgs a)
{
Application.Quit();
a.RetVal = true;
}
protected void OnButton1Clicked(object sender, EventArgs e)
{
label1.Text = "new text";
}
protected void OnLabel1PropertyNotifyEvent(object o, PropertyNotifyEventArgs args)
{
Console.WriteLine("label property change");
}
}
I have no idea what I do wrong, do I missing something?
Found a solution:
label1.AddNotification("label", (o, args) => {Console.WriteLine("label property change");});

Write/read to object

I would like to make a simple way to write/read to object element in WP7. Something is not working properly. My way of thinking and what I have already done is like that:
First I create a class that represents my object. I added static string just to see if everything works well:
namespace SimpleObject.Objects
{
public class Entry
{
public string entrytitle { get; set; }
public string entrycomment { get; set; }
public string entrycat = "works";
public Entry() { }
public Entry(string Entrytitle, string Entrycomment, string Entrycat)
{
this.entrytitle = Entrytitle;
this.entrycomment = Entrycomment;
this.entrycat = Entrycat;
}
public string entry { get; set; }
}
}
Then, as I read in some articles I need to make some changes in App.xaml.cs Here we go then:
using SimpleObject.Objects;
Before App() I put this:
public static Entry E;
Then in App() this:
UnhandledException += new EventHandler<ApplicationUnhandledExceptionEventArgs>(Application_UnhandledException);
E = new Entry();
InitializeComponent();
Then my UI is two pages. One is a form to input data, second to read. Under application bar button I have:
private void ApplicationBarIconButton_Click(object sender, System.EventArgs e)
{
Entry E = new Entry
{
entrytitle = TitleTextBox.Text,
entry = CommentTextBox.Text,
};
this.NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));
MessageBox.Show("Category added!");
}
Finally page that present results:
private void button1_Click(object sender, RoutedEventArgs e)
{
TextBlock1.Text = App.E.entrycat;
TextBlock2.Text = App.E.entrytitle;
}
And second TextBlock gives me nothing...
You're never setting the global static values. In your button click, it should be this:
private void ApplicationBarIconButton_Click(object sender, System.EventArgs e)
{
App.E.entrytitle = TitleTextBox.Text,
App.E.entrycat = CommentTextBox.Text,
this.NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));
}
another option is to forgo the global variable which you're basically only using to pass the value from one page to the next.
You can do this with query string values just like in a web application and pick them up on your page load handler.
private void ApplicationBarIconButton_Click(object sender, System.EventArgs e)
{
this.NavigationService.Navigate(new Uri("/Page2.xaml?title=TitleTextBox.Text&comment=CommentTextBox.Text", UriKind.Relative));
}

Update data in isolated storage

I have a code that adds email id and name in Isolated space. But it is not able to add multiple data. Also, how can I update in case any data was entered incorrectly?
namespace IsoStore
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
IsolatedStorageSettings.ApplicationSettings.Add("email", "someone#somewhere.com");
IsolatedStorageSettings.ApplicationSettings.Add("name", "myname");
}
private void button2_Click(object sender, RoutedEventArgs e)
{
textBlock1.Text = (string)IsolatedStorageSettings.ApplicationSettings["email"];
textBlock2.Text = (string)IsolatedStorageSettings.ApplicationSettings["name"];
}
}
}
Cleaned up your code a little for you, using a helper method to do the store:
namespace IsoStore
{
public partial class MainPage : PhoneApplicationPage
{
private IsolatedStorageSettings _appSettings;
// Constructor
public MainPage()
{
InitializeComponent();
_appSettings = IsolatedStorageSettings.ApplicationSettings;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
SaveSetting("email", "someone#somewhere.com");
SaveSetting("name", "myname");
}
private void button2_Click(object sender, RoutedEventArgs e)
{
textBlock1.Text = (string)_appSettings["email"];
textBlock2.Text = (string)_appSettings["name"];
}
private void SaveSetting( string setting, string value )
{
if (_appSettings.Contains(setting))
{
_appSettings[setting] = value;
}
else
{
_appSettings.Add(setting, value);
}
}
}
}
Try a few other examples to get your head around using IsolatedStorageSettings.
How to: Store and Retrieve Application Settings Using Isolated Storage
All about WP7 Isolated Storage - Store data in IsolatedStorageSettings
I have in mind 2 options, you either save your data to isolatedStorageFile MSDN Library OR ,this is what i might do in such case, You save under the key email all your emails as one string separate the emails with a char that is not allowed to be in an email, Coma "," lets say, when needed split your string and retrieve it to whatever makes you comfortable.
private void SaveSetting( string setting, string value )
{
if (_appSettings.Contains(setting))
{
_appSettings[settings] = _appSettings[settings] + "," + value;
}
else
{
_appSettings.Add(setting, value);
}
}
please note that this code segment is copied from HiTech Magic' answer.

unable to create and event handler for workbook/sheet event in a Addd-in

Im I'm using VS2008 Addin and im trying to write and event handler for a workbook inside the addin but unfortuantly it isn't getting fired can you help
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
FinalWorkbook = ExcelApplication.Workbooks.Add(missing);
FinalWorkbook.SheetActivate +=
new Excel.WorkbookEvents_SheetActivateEventHandler(
FinalWorkbook_ActivateSheet);
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
// MessageBox.Show("The addin has shutdown");
}
public void FinalWorkbook_ActivateSheet(object odjSheet)
{
sheet.BeforeRightClick += Worksheet_BeforeRightClick;
MessageBox.Show(sheet.Name + " Activated2");
}
void Worksheet_BeforeRightClick(Excel.Range Target, ref bool Cancel)
{
Cancel = true;
MessageBox.Show("Right-clicking in this sheet" +
" is not allowed.");
}
}
}
SheetActivate is only fired when you switch between sheets in the workbook, i.e. you click on Sheet2, then Sheet1 and so on.
If you Alt-Tab to a different application and come back to Excel, SheetActivate won't be fired.
You should look at Application.WorkbookActivate, Workbook.Activate or another event.

Toolbox items grayed out in VS 2010

I have tried numerous attempts to fix this problem or bug, firstly by deleting the .tbd files from C:\Users\\AppData\Local\Microsoft\VisualStudio\x.0
I have also tried this:
Visual Studio "Tools" menu
"Options" submenu
"Windows Form Designer" tab
"General" tab
Set "AutoToolboxPopulate" to "True"
The ToolBox list is still not populating correctly and the "BackgroundWorker" component I need is grayed out. Any ideas?
At least a workaround: declare the BackgroundWorker in code, but don't forget to dispose it properly:
public class MyForm : Form
{
private BackgroundWorker bgWorker = null;
public MyForm()
{
InitializeComponent();
this.bgWorker = new BackgroundWorker; //TODO: set properties and event handlers
}
public override void Dispose(bool disposing)
{
//TODO: copy from MyForm.Designer.cs and add:
Backgroundworker bgw = this.bgWorker;
this.bgWorker = null;
if (disposing && bgw != null)
{
try
{
//TODO: release event handlers
bgw.Dispose();
}
catch(Exception)
{
/* consumed disposal error */
}
}
}
}
I have found a solution to my problem, using the BackgroundWorker class in C# without using the component from the toolbox. In this case, I needed two seperate backgroundWorkers:
using System.Threading;
public partial class MainWindow : Window
{
private BackgroundWorker bw1 = new BackgroundWorker();
private BackgroundWorker bw2 = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
bw1.WorkerReportsProgress = true;
bw1.DoWork += new DoWorkEventHandler(bw1_DoWork);
bw1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw1_RunWorkerCompleted);
bw1.ProgressChanged += new ProgressChangedEventHandler(bw1_ProgressChanged);
bw2.WorkerReportsProgress = true;
bw2.DoWork += new DoWorkEventHandler(bw2_DoWork2);
bw2.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw2_RunWorkerCompleted);
bw2.ProgressChanged += new ProgressChangedEventHandler(bw1_ProgressChanged);
}
private void bw1_DoWork(object sender, DoWorkEventArgs e)
{
StatsProcessor proc = new StatsProcessor();
proc.CompareStats(listText1, listText2);
}
private void bw2_DoWork2(object sender, DoWorkEventArgs e)
{
StatsParser parser = new StatsParser();
}
private void bw1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar2.IsIndeterminate = false;
progressBar2.Value = 100;
btnCompareStats.IsEnabled = true;
}
private void bw2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.IsIndeterminate = false;
progressBar1.Value = 100;
btnFetchStats.IsEnabled = true;
}
private void bw1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar2.Value = e.ProgressPercentage;
}
private void bw2_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
private void btnCompare_Click(object sender, EventArgs e)
{
btnCompareStats.IsEnabled = false;
StatsProcessor proc = new StatsProcessor();
if (bw1.IsBusy != true)
{
progressBar2.IsIndeterminate = true;
// Start the asynchronous operation.
bw1.RunWorkerAsync();
}
}
private void btnFetchStats_Click(object sender, RoutedEventArgs e)
{
btnFetchStats.IsEnabled = false;
if (bw2.IsBusy != true)
{
progressBar1.IsIndeterminate = true;
// Start the asynchronous operation.
bw2.RunWorkerAsync();
}
}
}
I would try resetting the toolbox items. Then use the Add Item dialog to put back something you need.

Resources