Saving button text, path and icon when application closed - c#

I have made a little program that can start application (like quick launch in your taskbar)
You can add applications and it shows the icon of the .exe and the name of the file, and when you click on it (button) it starts the application.
When you close the program and start it again everything is empty, so i want to save it somewhere.
I see people on the internet do it with:
private void QuickStarter_FormClosed(object sender, FormClosedEventArgs e)
{
Properties.Settings.Default.Button1 = button1.Text;
Properties.Settings.Default.Save();
}
private void QuickStarter_Load(object sender, FormClosedEventArgs e)
{
button1.Text = Properties.Settings.Default.Button1;
}
This doesn't work, but they use it for text fields and input boxes i don't know if it is even possible for a button.
Question:
Can someone tell me what the best way is, for saving button input and load it back in when the application starts again? Or maybe i have to do it with a label or something?
Some little snippet that i use:
private void QuickStarter_Load(object sender, FormClosedEventArgs e)
{
button1.Text = Properties.Settings.Default.Button1;
}
Icon ico = null;
OpenFileDialog ofd = new OpenFileDialog();
string[] fileNames = new string[5];
private void application1ToolStripMenuItem_Click(object sender, EventArgs e)
{
ofd.Filter = "EXE|*.exe";
ofd.Title = "Add application";
if (ofd.ShowDialog() == DialogResult.OK)
{
ico = Icon.ExtractAssociatedIcon(ofd.FileName);
button1.Text = Path.GetFileNameWithoutExtension(ofd.FileName);
button1.Image = ico.ToBitmap();
button1.Enabled = true;
fileNames[0] = ofd.FileName;
}
}
private void button1_Click(object sender, System.EventArgs e)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = fileNames[0];
Process.Start(start);
}
private void QuickStarter_FormClosed(object sender, FormClosedEventArgs e)
{
Properties.Settings.Default.Button1 = button1.Text;
Properties.Settings.Default.Save();
}
}

Verifying the complaint
Using the following code works just fine for me, clicking the button will set the new text and closing and reloading the application will tell me when the button was last clicked.
private void Form1_Load(object sender, EventArgs e) {
button1.Text = Settings.Default.button1;
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
Settings.Default.button1 = button1.Text;
Settings.Default.Save();
}
private void button1_Click(object sender, EventArgs e) {
button1.Text = string.Format("Button was clicked at {0}", DateTime.Now);
}
You might have a problem with your applications permissions, if it isn't allowed to write to the %appdata% subfolders it won't be able to store the settings.
But it's also entirely possible you have some other problem in your solution. One that isn't immediately clear from your description. Make a minimal test project (like i did) and verify that you can't save and retrieve settings on a brand new test project.
Answering your question
Whenever you ask something along the lines of What is the optimal way to ... you are not going to get a conclusive answer and if i know anything about Stack Overflow i would say it's discouraged when you ask your question.
That said, here's how i would have done it.
Create a collection of data objects that implements the Serializable attributes. See Introducing XML Serialization
That collection would hold properties that describe your buttons, the text, the executable and (if applicable) their position using a Point structure.
I would deserialize that on load and serialize it on close (or better yet, when something changes)
I would (after deserialization) iterate the data objects in that collection and dynamically create the buttons at runtime, adding them to the Form's Controls like so:
Controls.Add(new Button { Text = "This is a new button!"});
I would also add some controls to add/remove entries from your data object collection. Or by using a context menu, either way works. Your design, your decisions.
As you get more confident with your coding you can move on to dragging and dropping buttons to order them or position them in your 'quicklaunch' application.

You need to add the button1 property to the Settings in the Settings.Designer.cs (or use the Settings.settings grid.
You also need to make sure that the "QuickStarter_FormClosed" event is fired when you're window is closed.
This is my Settings.Designer.cs:
namespace SettingsSaveTest.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string ButtonText {
get {
return ((string)(this["ButtonText"]));
}
set {
this["ButtonText"] = value;
}
}
}
}
I didn't notice it was for Windows Forms, and not WPF, but the same thing applies, you need to add the property to your settings.designer.
Here is my version in Windows Forms:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
button1.Text = Properties.Settings.Default.button1;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
button1.Text = "Saving...";
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
SaveProperties();
}
private void SaveProperties()
{
Properties.Settings.Default.button1 = textBox1.Text;
Properties.Settings.Default.Save();
}
private void button1_Click(object sender, EventArgs e)
{
button1.Text = textBox1.Text;
}
}
I also added the FormClosed eventhandler to the FormClosed stack:
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed);
I am also leaving my answer for WPF, since some other people might wonder. But the same thing applies. You need to add the property, and configure the event listeners.
This is my MainWindow.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Button1.Content = Properties.Settings.Default.ButtonText;
Closed += SaveSettings;
}
private void SaveSettings(object sender, EventArgs e)
{
SaveProperties();
}
private void SaveProperties()
{
Properties.Settings.Default.ButtonText = UserInput.Text;
Properties.Settings.Default.Save();
}
private void Button1_Click(object sender, RoutedEventArgs e)
{
SaveProperties();
Button1.Content = Properties.Settings.Default.ButtonText;
}
}
And finally my MainWindow.xaml
<Window x:Class="SettingsSaveTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox x:Name="UserInput" x:FieldModifier="public" HorizontalAlignment="Left" Height="23" Margin="48,105,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<Button x:Name="Button1" Content="Button" HorizontalAlignment="Left" Margin="203,105,0,0" VerticalAlignment="Top" Width="75" Click="Button1_Click"/>
</Grid>

Related

Display multiple groupboxes on winforms

So, in my WinForms application, I need to display several "pages" (that are groupboxes holding textbox, buttons, maskedbox and etc) on one main page on my application. Firstly I tried to use a "user controller", but it didn't work out because the name of the controllers didn't match the names that I passed to my database connection for example. So I tried to place these groupboxes one on top of another one via the "location property". All working just fine, but now I have a significant problem when I decide to make a few changes to these groupboxes controllers. It's very hard to access them and I wonder if there's another way to do so because it looks very amateur approach... How do I achieve this kind of functionality without placing groupboxes on top of another one? And I also wonder, is it correct to do it with groupbox or should I use panel?
An example of the approach:
private void btnCadastrarBeneficiario_Click(object sender, EventArgs e)
{
groupBoxUsuarioCadastro.Visible = false;
groupBoxClienteCadastro.Visible = false;
groupBoxHospitalCadastro.Visible = false;
GroupBoxMonitoramento.Visible = false;
groupBoxBeneficiarioCadastro.Visible = true;
}
I use the visibility property so I can show (or not) the groupbox and make them behave like an actual page.
---EDIT----
In order to make myself clear I created a minimal version of what I'm trying to show here:
namespace WinFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
groupBox2.Visible = false;
groupBox3.Visible = false;
groupBox1.Visible = true;
}
private void button2_Click(object sender, EventArgs e)
{
groupBox1.Visible = false;
groupBox3.Visible = false;
groupBox2.Visible = true;
}
private void button3_Click(object sender, EventArgs e)
{
groupBox1.Visible = false;
groupBox2.Visible = false;
groupBox3.Visible = true;
}
}
}
This is the code of a minimal application similar to what I'm doing. It works just fine, but I wonder if there's another way to do it, a more efficient, organized, and sophisticated way.
I would tend to do something like this:
private void button1_Click(object sender, EventArgs e)
{
HideAllBut(groupBox1);
}
private void button2_Click(object sender, EventArgs e)
{
HideAllBut(groupBox2);
}
private void HideAllBut(GroupBox groupToShow)
{
var groups = new[] {groupBox1, groupBox2};
foreach(var gb in groups)
{
gb.Visible = (gb == groupToShow);
}
}
You can obviously extend that to as many controls of whatever kind you like.

Checking if certain file\files exist

I want to make a windows form using C# to check if a file exist.
I've tried this one:
private void test_Click(object sender, EventArgs e)
{
var app1 = (#"C:\Users\frangon\Desktop\Spectrum-Check.EXE");
test.Text = File.Exists(app1).ToString();
}
If possible, I don't want to click it. I just want it to show as "True" if the file exist, or "False" if the file doesn't exist.
You can add an event to trigger when the form loads:
And then in your code behind:
private void Form1_Load(object sender, EventArgs e)
{
string app1 = #"C:\Users\frangon\Desktop\Spectrum-Check.EXE";
test.Text = File.Exists(app1).ToString();
}

custom tooltip in c# .net win forms

I am looking to simulate a custom tooltip the like of you see in websites using c# .NET 4.5 windows forms.This tooltip will basically show status of some Tasks like how many tasks are pending,tasks in process, completed etc.To do this i am using a borderless win form.This winform will have some texts, images etc.I want it to reveal itself on button's mouseHover event and disappear on MouseLeave event.My problem is that on Mousehover event numerous instances of that tooltip form is getting generated and on MouseLeave they are not getting closed.My code is
private void B_MouseHover(object sender, EventArgs e)
{
frmSecQStatToolTipDlg tooltip = new frmSecQStatToolTipDlg();
tooltip.Location = this.PointToScreen(new Point(this.Left, this.Bottom));
tooltip.Show();
}
private void B_MouseLeave(object sender, EventArgs e)
{
frmSecQStatToolTipDlg tooltip = new frmSecQStatToolTipDlg();
tooltip.Close();
}
My code is not working, hence please tell me how to do this the correct way.Thanks
You're generating a new instance of the form class every time you get a hover event, and every time you get a leave event. If you want to continue to use this approach I would recommend you use a variable on your main form object to store the reference to your tooltip form. Secondly, you need to not generate a new instance whenever the event handler is called, but only when necessary. I would create your instance the first time your Hover event is called for a particular control, and then dispose of it when your Leave handler is called -- this is under the assumption that the tooltip dialog's constructor loads up different information for each control being hovered over. Like so:
frmSecQStatToolTipDlg f_tooltip;
private void B_MouseHover(object sender, EventArgs e)
{
if(frmSecQStatToolTipDlg == null)
{
f_tooltip = new frmSecQStatToolTipDlg();
}
tooltip.Location = this.PointToScreen(new Point(this.Left, this.Bottom));
tooltip.Show();
}
private void B_MouseLeave(object sender, EventArgs e)
{
if(f_tooltip != null)
{
f_tooltip.Close();
f_tooltip = null;
}
}
You should keep a global field for this form, and should not dispose or close it. Just hide it on some events and show again.
Sample Code:
frmSecQStatToolTipDlg tooltip;
private void B_MouseHover(object sender, EventArgs e)
{
if(frmSecQStatToolTipDlg == null)
{
tooltip = new frmSecQStatToolTipDlg();
}
tooltip.Location = this.PointToScreen(new Point(this.Left, this.Bottom));
tooltip.Show();
}
private void B_MouseLeave(object sender, EventArgs e)
{
if(frmSecQStatToolTipDlg != null)
{
tooltip.Hide();
}
}
With this logic you'll not have to create tooltip instance again and again and it will not take time to popup if you frequently do this activity.
Declare your tooltip once as readonly and use it without asking anytime if it is null or not.
If you need to Dispose it, implement the IDisposable pattern:
https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx
private readonly frmSecQStatToolTipDlg _tooltip = new frmSecQStatToolTipDlg() ;
private void B_MouseHover(object sender, EventArgs e)
{
_tooltip.Location = this.PointToScreen(new Point(this.Left, this.Bottom));
_tooltip.Show();
}
private void B_MouseLeave(object sender, EventArgs e)
{
_tooltip.Hide();
}

Remeber Me C# app setting

I Create login form and want to put "remember me" check box on it.
But every time i open program it doesn't change.
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
Project.Properties.Settings.Default.rememberMe = true;
Project.Properties.Settings.Default.Save();
}
else
{
Project.Properties.Settings.Default.rememberMe = false;
Project.Properties.Settings.Default.Save();
}
}
Also i want to save user login information, should i save them in app setting just like remember me setting or there is better way?
You're saving the settings, but you need to retrieve those settings too.
Subscribe to the Form's load event and set the value of the CheckBox.
private void Form1_Load(object sender, EventArgs e)
{
checkBox1.Checked = Project.Properties.Settings.Default.rememberMe;
}
Also, and this is just common practice, but your code could be shorter:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
Project.Properties.Settings.Default.rememberMe = checkBox1.Checked;
Project.Properties.Settings.Default.Save();
}

in c#, how can you disable a button after the 1st click, and enable it again after you click another button?

I cannot figure this out
i'm making a windows form application with visual basic in c#
i have a scan button and it scans everything in the folder and lists all of the files in the listbox
if you click it another time the list of files appear again
how can you make it so you can only press the scan button once, and then you can press it again if you click the browse button?
the browse button is to select the folder you want to scan
thanks
This is pretty trivial
private void ScanButtonClick(object sender, EventArgs e)
{
// do something
(sender as Button).Enabled = false;
}
private void BrowseButtonClick(object sender, EventArgs e)
{
ScanButton.Enabled = true;
}
Its a bit unclear if you're writing in C# or vb.net, but since the question is tagged as C#...
private void btnScan_Click(object sender, EventArgs e) {
btnScan.Enabled = false;
// other code here
}
private void btnBrowse_Click(object sender, EventArgs e) {
btnScan.Enabled = true;
//other code here
}
I tried this in my windows form application in C# and it works fine!
private void button3_Click_1(object sender, EventArgs e)
{
int count = 0;
count++;
//add your code here
if (count == 1) {
button3.Enabled = false;
//only one click allowed
}
}

Categories

Resources