How can I show/hide form with checkbox? - c#

Sorry, I am new to C# and am unsure what I am doing wrong.
Here is the code I am using:
private void chkSmallMenu_CheckedChanged(object sender, EventArgs e)
{
frmSmallMenu sm = null;
if (chkSmallMenu.Checked)
{
if (sm is null || sm.IsDisposed)
{
sm = new frmSmallMenu();
}
sm.Show();
}
else
{
MessageBox.Show("close");
sm?.Close();
}
}
The window will open but when I uncheck the box nothing happens and I have no idea why.
I have tried looking for an answer but nothing has worked for me.

Try this:
frmSmallMenu sm = new frmSmallMenu();
private void chkSmallMenu_CheckedChanged(object sender, EventArgs e)
{
if (chkSmallMenu.Checked == true)
{
sm.Show();
}
else
{
MessageBox.Show("close");
sm.Hide();
}
}

This modification of your code would probably do what you want by first looking whether the other Form is already running or not:
namespace WinFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// The following `uselessField ` is a `field`. See also https://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property
/// `(Since it is `unused`, you would get a CS0169 Warning in the "Error List" window)
private int uselessField;
/// <summary>
/// **Event handler** of the "chkSmallMenu" `CheckBox` control on your `Form`.
/// (You would probably get an IDE1006 Info in your "Error List" window because
/// the control name and/or the event handler name respectively, starts with a lower case
/// https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/naming-rules)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void chkSmallMenu_CheckedChanged(object sender, EventArgs e)
{
// the following `sm` is a `variable`. See also https://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property
var sm = Application.OpenForms.OfType<frmSmallMenu>().FirstOrDefault();
// the following `Checked` **property** belongs to the WinForms Checkbox class and `IsDisposed` belongs to the other `Form`
if (chkSmallMenu.Checked)
{
if (sm?.IsDisposed != true)
{
sm = new frmSmallMenu();
}
sm.Show();
}
else
{
MessageBox.Show("close");
sm?.Close();
}
}
}
}

This fixed my issue:
frmSmallMenu sm = new frmSmallMenu();
private void chkSmallMenu_CheckedChanged(object sender, EventArgs e)
{
if (chkSmallMenu.Checked == true)
{
sm.Show();
}
else
{
MessageBox.Show("close");
sm.Hide();
}
}

Related

Creating a "Team" in another window(TeamCreatorWindow) and save the object to be displayed in a "Listbox" in Main Window EDITED

namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// Function for creating Team
public void AddToListBox(string MyTeam)
{
AddTeamBox.Items.Add(MyTeam);
}
private void AddTeam_Click(object sender, RoutedEventArgs e)
{
TeamCreatorWindow TeamCreatorPopup = new TeamCreatorWindow();
TeamCreatorPopup.Show();
}
}
}
this is the code for my "MainWindow"
namespace WpfApp1
{
/// <summary>
/// Interaction logic for TeamCreatorWindow.xaml
/// </summary>
public partial class TeamCreatorWindow : Window
{
public string NameTeam;
public string KeyPlayer;
public string Knep;
public TeamCreatorWindow()
{
InitializeComponent();
}
class CreatedTeam : TeamCreatorWindow
{
public CreatedTeam(string TeamName, string TeamKnep, string KeyPlayers)
{
TeamName = NameTeam;
TeamKnep = Knep;
KeyPlayers = KeyPlayer;
}
}
private void CancelTeamCreator_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void CreateTeambutton_Click(object sender, RoutedEventArgs e)
{
CreatedTeam team = new CreatedTeam(NameTeam, Knep, KeyPlayer);
}
private void KeyPlayerTxtBox_KeyDown(object sender, KeyEventArgs e)
{
KeyPlayer = KeyPlayerTxtBox.Text;
}
private void TeamNameTxtBox_KeyDown(object sender, KeyEventArgs e)
{
NameTeam = TeamNameTxtBox.Text;
}
private void HemmaButton_Click(object sender, RoutedEventArgs e)
{
HemmaButton.IsChecked = true;
BortaButton.IsChecked = false;
HemmaButton.BorderBrush = Brushes.Green;
BortaButton.BorderBrush = Brushes.Gray;
Knep = HemmaBlock.Text;
}
private void BortaButton_Click(object sender, RoutedEventArgs e)
{
BortaButton.IsChecked = true;
HemmaButton.IsChecked = false;
HemmaButton.BorderBrush = Brushes.Gray;
BortaButton.BorderBrush = Brushes.Green;
Knep = BortaBlock.Text;
}
}
}
This is code for the "TeamCreatorWindow" here i am getting information for the teams from TextBoxes and storing the text into strings( TeamName, Knep and KeyPlayer) i have a CreateTeamButton, when the CreateTeamButton is clicked it should store the Object into The listBox from Mainwindow called "AddTeamBox". I have tried creating a public function in mainwindow called "AddToListBox" but i cant access it in my TeamCreatorWindow anyway. what is the right way to do this?

Showing a new page it unchecks my checkboxes. How do I prevent it?

So I have this application where you can select from different pages, Like a page navigation system..
And I have a checkbox on both of them.
And if I check a checkbox on SecondPage(); and then go to thirdPage(); the checkbox on SecondPage(); will be unchecked, how do I prevent this?
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
bool isCHecked = true;
private void button_Click(object sender, RoutedEventArgs e)
{
main.Content = new SecondPage();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
main.Content = new thirdPage();
}
}
You are always creating a new instance of the pages so it will be a fresh copy, and the state that was previously there would be lost, one of that solution is to create fields in your main window like:
namespace CheckboxesAndPages
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private thirdPage _thirdPage;
private SecondPage _SecondPage;
public MainWindow()
{
InitializeComponent();
}
bool isCHecked = true;
private void button_Click(object sender, RoutedEventArgs e)
{
_SecondPage = _SecondPage != null ? _SecondPage : new SecondPage();
main.Content = _SecondPage;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
_thirdPage = _thirdPage !=null ? _thirdPage : new thirdPage();
main.Content = _thirdPage;
}
}
or you can create Properties as well:
namespace CheckboxesAndPages
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private thirdPage _thirdPage;
private SecondPage _SecondPage;
private ThirdPage ThirdPage
{
get
{
_thirdPage = _thirdPage !=null ? new thirdPage();
return _thirdPage;
}
set
{
_thirdPage = value;
}
}
private SecondPage SecondPage
{
get
{
_SecondPage= _SecondPage!=null ? new SecondPage();
return _SecondPage;
}
set
{
_SecondPage= value;
}
}
private SecondPage _SecondPage;
public MainWindow()
{
InitializeComponent();
}
bool isCHecked = true;
private void button_Click(object sender, RoutedEventArgs e)
{
main.Content = SecondPage;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
main.Content = ThirdPage;
}
}
or you can write null condition like:
_SecondPage = _SecondPage ?? new SecondPage();

How to share data from one view to another?

I have some problems with simple variable sharing between different views.
I have first main view called MainPage.xaml and second called Page2.xaml.
I want to check which radiobutton on MainPage.xaml is checked and send a variable with that date to Page2.xaml.
MainPage:
namespace IDG
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public string choice;
public MainPage()
{
this.InitializeComponent();
}
private void bt_start_Click(object sender, RoutedEventArgs e)
{
if (rb_choice1.IsChecked == true)
{
choice = "choice1";
}
if (rb_quiz.IsChecked == true)
{
this.Frame.Navigate(typeof(Page2), choice);
}
}
}
}
And Page2:
namespace IDG
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Page2 : Page
{
private string x;
public Page2()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var param = e.Parameter as string;
x = param;
textBlock1.Text = x;
}
private void button_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(MainPage));
}
}
}
And I want this parameter to be stored in main class, how to do it?
On Page 2 in the OnNavigatedTo event retreive the value like this: var param = e.Parameter as string
EDIT
Assign the retreived parameter to the textblock in the OnNavigatedTo. At the time the page is constructed the value of x is "".
public sealed partial class Page2 : Page
{
private string x="";
public Page2()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
x = e.Parameter as string;
textBlock1.Text = x;
}
private void button_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(MainPage));
}
}
Recently, I'm working on WPF project but we use it with DevExpress library, and for your issue, it's very easy to be fixed with Messenger in DevExpress.
We just register the messenger where you want to receive the data,
public class Message {
//...
}
public class Recipient {
public Recipient() {
Messenger.Default.Register<string>(this, OnMessage1);
Messenger.Default.Register<Message>(this, OnMessage2);
}
void SendMessages() {
Messenger.Default.Send("test");
Messenger.Default.Send(new Message());
}
void OnMessage1(string message) {
//...
}
void OnMessage2(Message message) {
//...
}
}
And then you can send it from another view,
public class InheritedMessage : Message {
//...
}
public class Recipient {
public Recipient() {
//Inherited messages are not processed with this subscription
Messenger.Default.Register<Message>(
recipient: this,
action: OnMessage);
//Inherited messages are processed with this subscription
Messenger.Default.Register<Message>(
recipient: this,
receiveInheritedMessagesToo: true,
action: OnMessage);
}
void SendMessages() {
Messenger.Default.Send(new Message());
Messenger.Default.Send(new InheritedMessage());
}
void OnMessage(Message message) {
//...
}
}
With it, you can pass data between modules (or views, but recommend to use MVVM)
If you want to know more about DevExpress, please go through https://documentation.devexpress.com/#WPF/CustomDocument17474
Hope it could help you. :)

Rate limiting on the KeyUp event handler in C#

I'm wanting to validate the input on a text field as a user types. This functionality works fine, however I would like to rate limit the validation as it's hitting an external API. I'd like to only perform a validation after a user has not typed for 750ms.
ATM I'm simply using this:
private void Configure_Load(object sender, EventArgs e)
{
endpointBox.KeyUp += EndpointBox_KeyUp;
}
void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{
TestHTTP200(endpointBox.Text);
}
Use a Timer Control
System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
private void Configure_Load(object sender, EventArgs e)
{
endpointBox.KeyUp += EndpointBox_KeyUp;
myTimer.Tick +=new EventHandler(OnTimedEvent); //EDIT: should not be `ElapsedEventHandler`
myTimer.Interval=750;
}
void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{
myTimer.Stop();
myTimer.Start();
}
private void OnTimedEvent(Object myObject,EventArgs myEventArgs)
{
myTimer.Stop();
TestHTTP200(endpointBox.Text);
}
You would want a method equal to JavaScript's SetTimeout method. This can be cancelled when the user provides more input:
Code taken from here.
public static IDisposable SetTimeout(Action method, int delayInMilliseconds)
{
System.Timers.Timer timer = new System.Timers.Timer(delayInMilliseconds);
timer.Elapsed += (source, e) =>
{
method();
};
timer.AutoReset = false;
timer.Enabled = true;
timer.Start();
// Returns a stop handle which can be used for stopping
// the timer, if required
return timer as IDisposable;
}
You can then use this in your key up handler:
void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{
IDisposable timeout = SetTimeout(() => TestHTTP200(endpointBox.Text), 750);
if (this.currentTimeout != null) {
this.currentTimeout.Dispose();
this.currentTimeout = timeout;
}
}
This is the basic principle at least, every time the user types you reinitiate a 750ms timeout to do your thing, and cancel any pending timers.
Update: complete code sample:
public partial class Form1 : Form
{
private IDisposable currentTimeout;
public Form1()
{
InitializeComponent();
}
private void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{
IDisposable timeout = TimerHelper.SetTimeout(() => TestHTTP200(EndpointBox.Text), 750);
if (this.currentTimeout != null)
{
this.currentTimeout.Dispose();
this.currentTimeout = timeout;
}
}
private void TestHTTP200(string text)
{
//...
}
}
public class TimerHelper
{
public static IDisposable SetTimeout(Action method, int delayInMilliseconds)
{
System.Timers.Timer timer = new System.Timers.Timer(delayInMilliseconds);
timer.Elapsed += (source, e) =>
{
method();
};
timer.AutoReset = false;
timer.Enabled = true;
timer.Start();
// Returns a stop handle which can be used for stopping
// the timer, if required
return timer as IDisposable;
}
}
using System;
namespace Azine_Library.Misc
{
/// <summary>
/// Represents a way to delay something, eg. something an event handler does, update-ion of a control, object or to run a method, This class '<see cref="DelayUpdate"/>'
/// is intended to be used as a delayer of some sort and contains an event, '<see cref="PushUpdate"/>' that would be subcribed to an event handler where then the code
/// intended to be delayed would go. This object also contains a method, '<see cref="delay"/>' that when called delays the code written/located within the event handler
/// that is handling the '<see cref="PushUpdate"/>' event. The method, <see cref="delay"/> should be called from an event handler or a method of some sort that would orginally
/// execute the code written/located within the event handler described above also. An example of how this object can interact with another object is described and documented in great detail
/// within the documentation for "Azine_Library", also an example program is available with the documentation.
/// </summary>
public class DelayUpdate
{
// Written, 17.06.2017
#region Fields / Properties
/// <summary>
/// Occurs when the provided time (interval:) has elapsed
/// </summary>
public event EventHandler PushUpdate;
/// <summary>
/// READONLY. the amount of times the timer has ticked since the last call to delay, (DelayUpdate.delay).
/// </summary>
public int updateCounter
{
get;
private set;
}
/// <summary>
/// The amount of time [this] waits for until it pushes the update. (Milliseconds). default value: '500'.
/// </summary>
public int interval
{
get;
set;
}
/// <summary>
/// Holds the amount of times [this] raises the "DelayUpate.PushUpdate" event every call to DelayUpdate.delay() method. default value: '1'.
/// </summary>
public int updatesPerPush
{
get;
set;
}
private System.Diagnostics.Stopwatch stopWatch;
private System.Windows.Forms.Timer timer;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of type, 'DelayUpdate'; sets the classes' properties to the defaults.
/// </summary>
public DelayUpdate()
{
//Initializing Variables
this.updateCounter = 0;
this.interval = 500;
this.updatesPerPush = 1;
this.stopWatch = new System.Diagnostics.Stopwatch();
this.timer = new System.Windows.Forms.Timer();
//Sub-ing Events
this.timer.Tick += this.Timer_Tick;
}
#endregion
#region Methods
/// <summary>
/// Delays the raising of the event, PushUpdate; call this method when a property of an object has changed. eg, TextBox.TextChanged => DelayUpdate.delay();
/// </summary>
public void delay()
{
// Written, 13.06.2017
this.timer.Start();
this.stopWatch.Restart();
this.updateCounter = 0;
}
#endregion
#region Events
/// <summary>
/// Raises the 'DelayUpdate.PushUpdate' event.
/// </summary>
private void onPushUpdate()
{
//Written, 26.05.2017 : 5:22pm
if (PushUpdate != null)
PushUpdate.Invoke(this, new EventArgs());
}
#endregion
#region Event Handlers
private void Timer_Tick(object sender, EventArgs e)
{
// Written, 13.06.2017
if (this.stopWatch.ElapsedMilliseconds > this.interval)
{
if (this.updateCounter < this.updatesPerPush)
{
this.timer.Stop();
this.onPushUpdate();
}
this.updateCounter++;
}
}
#endregion
}
}
And this is how you would use this class, DelayUpdate.cs:
Say you have a WinForm that searches a directory for files which has a textbox called, "search_textBox" and has a textChanged event handler attached, :
namespace DelayUpdateExample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.search_textBox.TextChanged += this.Search_textBox_TextChanged;
}
private void Search_textBox_TextChanged(object sender, EventArgs e)
{
}
}
}
You would make a reference to the class, DelayUpdate.cs and initialize it. Subscribe to the DelayUpdate.PushUpdate event like so:
private DelayUpdate delayUpdate;
public Form1()
{
InitializeComponent();
this.delayUpdate = new DelayUpdate()
{
interval = 500,
updatesPerPush = 1,
};
this.delayUpdate.PushUpdate += this.DelayUpdate_PushUpdate;
this.search_textBox.TextChanged += this.Search_textBox_TextChanged;
}
private void DelayUpdate_PushUpdate(object sender, EventArgs e)
{
throw new NotImplementedException();
}
Within the textChanged event handler you would make a call to DelayUpdate.delay() like so..
private void Search_textBox_TextChanged(object sender, EventArgs e)
{
this.delayUpdate.delay();
}
And the code that you would want to delay would then go in the DelayUpdate_PushUpdate(object, EventArgs) that you subscribed to. like so:
private void DelayUpdate_PushUpdate(object sender, EventArgs e)
{
// You would search the directory here..
// Code that you want to delay would go here.
}

How to change button background image on mouseOver?

I have img1, and img2 in my resources. I have easily set btn.backgroundImage as img1 in btn properties. Images paths are: c:\Project\Resources...
Now I don't know how to set btn.backgroundImage to be img2, I want to do it on event "MouseEnter". So I would apreciate complete code, because I am pretty green about this...
I apreciate any given idea...
In the case of winforms:
If you include the images to your resources you can do it like this, very simple and straight forward:
public Form1()
{
InitializeComponent();
button1.MouseEnter += new EventHandler(button1_MouseEnter);
button1.MouseLeave += new EventHandler(button1_MouseLeave);
}
void button1_MouseLeave(object sender, EventArgs e)
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img1));
}
void button1_MouseEnter(object sender, EventArgs e)
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img2));
}
I would not recommend hardcoding image paths.
As you have altered your question ...
There is no (on)MouseOver in winforms afaik, there are MouseHover and MouseMove events, but if you change image on those, it will not change back, so the MouseEnter + MouseLeave are what you are looking for I think. Anyway, changing the image on Hover or Move :
in the constructor:
button1.MouseHover += new EventHandler(button1_MouseHover);
button1.MouseMove += new MouseEventHandler(button1_MouseMove);
void button1_MouseMove(object sender, MouseEventArgs e)
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img2));
}
void button1_MouseHover(object sender, EventArgs e)
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img2));
}
To add images to your resources: Projectproperties/resources/add/existing file
I think something like this:
btn.BackgroundImage = Properties.Resources.*Image_Identifier*;
Where *Image_Identifier* is an identifier of the image in your resources.
I made a quick project in visual studio 2008 for a .net 3.5 C# windows form application and was able to create the following code. I found events for both the enter and leave methods.
In the InitializeComponent() function. I added the event handler using the Visual Studio designer.
this.button1.MouseLeave += new System.EventHandler( this.button1_MouseLeave );
this.button1.MouseEnter += new System.EventHandler( this.button1_MouseEnter );
In the button event handler methods set the background images.
/// <summary>
/// Handles the MouseEnter event of the button1 control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void button1_MouseEnter( object sender, EventArgs e )
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img2));
}
/// <summary>
/// Handles the MouseLeave event of the button1 control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void button1_MouseLeave( object sender, EventArgs e )
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img1));
}
You can create a class based on a Button with specific images for MouseHover and MouseDown like this:
public class AdvancedImageButton : Button {
public Image HoverImage { get; set; }
public Image PlainImage { get; set; }
public Image PressedImage { get; set; }
protected override void OnMouseEnter(System.EventArgs e) {
base.OnMouseEnter(e);
if (HoverImage == null) return;
if (PlainImage == null) PlainImage = base.Image;
base.Image = HoverImage;
}
protected override void OnMouseLeave(System.EventArgs e) {
base.OnMouseLeave(e);
if (HoverImage == null) return;
base.Image = PlainImage;
}
protected override void OnMouseDown(MouseEventArgs e) {
base.OnMouseDown(e);
if (PressedImage == null) return;
if (PlainImage == null) PlainImage = base.Image;
base.Image = PressedImage;
}
}
This solution has a small drawback that I am sure can be fixed: when you need for some reason change the Image property, you will also have to change the PlainImage property also.

Categories

Resources