How to implement a graphical 3-Way "Switch" - c#

I'm trying to build a 3-Way "Switch" in my WinForms project.
It only sends one command for all three "settings", but should alternate between 3 different background images each time the user clicks on the button. I've already implemented a 2-Way toggle switch into my project by using a CheckBox with it's appearance set to "Button", but I don't believe this method will work for a 3-Way switch.
Here is the code that I've tried, but it doesn't seem to do anything when the button is clicked:
private void ThreeWayButton_Click(object sender, EventArgs e)
{
if (ThreeWayButton.BackgroundImage.Equals(Properties.Resources.ThreeWay_1))
{
ThreeWayButton.BackgroundImage = Properties.Resources.ThreeWay_2;
}
else if (ThreeWayButton.BackgroundImage.Equals(Properties.Resources.ThreeWay_2))
{
ThreeWayButton.BackgroundImage = Properties.Resources.ThreeWay_3;
}
else if (ThreeWayButton.BackgroundImage.Equals(Properties.Resources.ThreeWay_3))
{
ThreeWayButton.BackgroundImage = Properties.Resources.ThreeWay_1;
}
}
Another method I tried is using a switch:
static int switch_state = 0;
//...
protected void ThreeWayButton_Click(object sender, EventArgs e)
{
switch_state++;
switch (switch_state)
{
case 1:
ThreeWayButton.BackgroundImage = Properties.Resources.ThreeWay_2;
break;
case 2:
ThreeWayButton.BackgroundImage = Properties.Resources.ThreeWay_3;
break;
case 3:
ThreeWayButton.BackgroundImage = Properties.Resources.ThreeWay_1;
break;
default:
break;
}
}
This method kind of works; it cycles through the three images, but once it gets to the last one, it doesn't cycle through the images again.
If the second method is the appropriate one to use, I'd like it to revert back to case 1 after the user clicks on the button when the switch_state is case 3
It should cycle between the three images each time the user clicks the button, no matter how many times the button has been clicked.

Your second approach is the good one, you just need to add:
if(switch_state > 3)
switch_state = 1;
Just after your switch_state++, else it will continue incrementing thus doing nothing.

Related

How to refer to 1 instance of winform instead of making a new Instance

Regarding to my previous question, It is very helpful to know what I am doing wrong but still I cannot make it work with only making one instance, this is the current code so far, It is supposed to change the value of a textbox in one form without making a new form.
Form 2:
private void btnAward2_Click(object sender, EventArgs e)
{
display.RevealItems(2);
}
private void btnAward3_Click(object sender, EventArgs e)
{
display.RevealItems(3);
}
private void btnAward4_Click(object sender, EventArgs e)
{
display.RevealItems(4);
}
Form 1:
public void RevealItems(int ItemNo)
{
Items zItems = JsonSerializer.Deserialize<Items>(File.ReadAllText(FilePath()));
switch (ItemNo)
{
case 1:
Item1.Text = zItems.ItemArray[0];
Score1.Text = zItems.ScoreArray[0];
InitializeComponent();
break;
case 2:
Item2.Text = zItems.ItemArray[1];
Score2.Text = zItems.ScoreArray[1];
InitializeComponent();
break;
case 3:
Item3.Text = zItems.ItemArray[2];
Score3.Text = zItems.ScoreArray[2];
InitializeComponent();
break;
case 4:
Item4.Text = zItems.ItemArray[3];
Score4.Text = zItems.ScoreArray[3];
InitializeComponent();
break;
case 5:
Item5.Text = zItems.ItemArray[4];
Score5.Text = zItems.ScoreArray[4];
InitializeComponent();
break;
case 6:
Item6.Text = zItems.ItemArray[6];
Score6.Text = zItems.ScoreArray[6];
InitializeComponent();
break;
}
}
I tried many answers in the internet but It didn't work.
Remember that forms are just classes. You track instances of forms like you track instances of any other class: by storing a reference to the instance in a variable. For a given form on the screen, you need to know what variables you used for the form when first calling the .Show() or .ShowDialog() methods, and make sure to use the same variable (or a copy of the variable) at later points where you refer to the form.
In a Winforms project, this means going all the way back to the startup of the program, because there are different ways in the Visual Studio project you might set the program to start and show the initial form. We don't have that information in the question, so this is as far as I can take you at the moment.

Xamarin: Is there a Way to Differentiate Between a Swipe and a BottomNavigationView Click?

I am wondering if it's possible to differentiate between a swipe and a click on the BottomNavigationView in Xamarin.Android.
I've implemented:
void NavigationView_NavigationItemSelected(object sender, BottomNavigationView.NavigationItemSelectedEventArgs e)
{
if (_viewPager.CurrentItem == 0)
{
_fm1.Pop2Root();
}
_viewPager.SetCurrentItem(e.Item.Order, true);
}
but there is no differentiation between a swipe and a click. I want to keep the current page loaded if the user swipes, but pop to the root if the user has clicked on the currently selected BottomNavigationView tab.
And here's what my Pop2Root method looks like (not that it really matters):
public void Pop2Root()
{
_wv.LoadUrl("https://www.bitchute.com/");
}
I just want a separate event for click versus swipe.
I'm not looking for anyone to do my work. I will post the full solution (as always) once I've figured it out. What I'm looking for is a yes or no answer whether or not it's possible; then I'll take care of the rest. I've implemented a click listener on the TabHost before, but that's a completely different UI element:
https://github.com/hexag0d/BitChute_Mobile_Android_a2/blob/2.7641/Activities/ClickListeners.cs
If you would like more context on the complete project, here's the MainActivity.cs then you can back into the rest:
https://github.com/hexag0d/BitChute_Mobile_Android_BottomNav/blob/master/MainActivity.cs
Thanks, in advance
The answer to this question is yes. The ViewPager_PageSelected method is invoked when user swipes. The NavigationView_NavigationItemSelected is invoked on a tab press. Interestingly, if ViewPager_PageSelected method is put before NavigationView_NavigationItemSelected method, ViewPager_PageSelected won't be invoked when the user presses the a tab until after this method is called:
_viewPager.SetCurrentItem(e.Item.Order, true);
After that happens, the ViewPager_PageSelected method is invoked and NavigationView_NavigationItemSelected gets invoked again. So I decided to do the order like this and set a custom int. This way, both methods are only called once per user interaction, and there is differentiation.
(Note events BottomNavigationView.NavigationItemSelectedEventArgs & ViewPager.PageSelectedEventArgs)
//put all of this inside your MainActivity.cs
int _tabSelected;
void NavigationView_NavigationItemSelected(object sender, BottomNavigationView.NavigationItemSelectedEventArgs e)
{
if (_tabSelected == e.Item.Order)
{
switch (_viewPager.CurrentItem)
{
case 0:
_fm1.Pop2Root();
break;
case 1:
_fm2.Pop2Root();
break;
case 2:
_fm3.Pop2Root();
break;
case 3:
_fm4.Pop2Root();
break;
case 4:
_fm5.Pop2Root();
break;
}
}
else
{
_viewPager.SetCurrentItem(e.Item.Order, true);
}
}
private void ViewPager_PageSelected(object sender, ViewPager.PageSelectedEventArgs e)
{
_menu = _navigationView.Menu.GetItem(e.Position);
_navigationView.SelectedItemId = _menu.ItemId;
_tabSelected = _viewPager.CurrentItem;
}

How to use Radio Buttons in WindowsFormsApplications? How to check if changed?

I'm working on a small program that will output a string to aid in awarding financial aid scholarships. Scholarships have a type, may or may not have a tier, and if they are "transfer" scholarships, must be either 4 semesters, 6 semesters, or 8 semesters.
I'm new to using Windows Forms Applications, so please keep the answers as simple as possible since I am working on beginner projects.
(Please excuse me if I use the wrong terminology here, but I will describe as best I can what I've tried)
I need to "access" the radio buttons and check to see if they have been ticked. I also have no idea how to update to see if it has been changed.
I have all of my code in comboBox1_SelectIndexChained, and I am guessing that I will need to break this up into different methods such as radiobutton1.CheckChanged, etc.
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Object m = comboBox1.SelectedItem;
string stringM = m.ToString();
if (radioButton1.Checked && radioButton2.Checked)
{
MessageBox.Show("Error. Student cannot receive Tier 1 and Tier 2.");
Form1 NewForm = new Form1();
NewForm.Show();
this.Dispose(false);
}
switch (stringM)
{
case "Distinguished Freshman":
MessageBox.Show("####");
break;
case "Presidential Scholarship (Tier 1: $9,500)":
if(radioButton1.Checked)
{
MessageBox.Show("P1H183S 9500");
}
else if(radioButton2.Checked)
{
MessageBox.Show("P1H183S 9000");
}
break;
case "University Centurium (Tier 1: $7,000)":
if (radioButton1.Checked)
{
MessageBox.Show("1UC183S 7000");
}
else if (radioButton2.Checked)
{
MessageBox.Show("1UC183S 6500");
}
break;
case "Red and Gray (Tier 1: $4,000)":
if (radioButton1.Checked)
{
MessageBox.Show("1RG183S 4000");
}
else if (radioButton2.Checked)
{
MessageBox.Show("1RG183S 3500");
}
break;
case "Reddie Achievement":
MessageBox.Show("RAF 183S ####");
break;
case "Transfer (Tier 1: $4,500)":
if (radioButton1.Checked)
{
MessageBox.Show("P1H182S 9500");
}
else if (radioButton2.Checked)
{
MessageBox.Show("P1H182S 9000");
}
break;
case "Transfer (Tier 2: $4,000)":
break;
}
}
I want the user to use a ComboBox to select the scholarship name, then choose Tier 1 or Tier 2 if necessary, then choose 4, 6, or 8 semesters if (AND ONLY IF) the scholarship is a transfer scholarship. There is a clear button to clear the entire form at the bottom and a submit button. When the submit button is selectd, I want it to print a string that can be copied/pasted. (Will a MessageBox work fine for this, or does anyone have any better suggestions?)
Thank you all so much in advance for your help!

C# - DataGridView - having unique CellClick events based on content

I have a design question about what the best approach is when you want to have different actions happen when a user clicks on a cell in a DataGridView, based on what type of information is in that cell.
Imagine the following scenario. There is a package delivery system and one of the screens shows a list of all deliveries currently scheduled. Columns could include:
Delivery Number
Customer Number
Customer Delivery Location
Primary Contact
Delivery Order Receipt
If the user would click on a cell the action should be different based on what the column is. For example, if the user clicks on “Customer Delivery Location” it might open up a Delivery Location window which allows them to view/edit location details. If the user clicks on “Delivery Order Receipt” it might open a PDF window showing the receipt for the order.
The simple way to do this would be to do an If statement on the CellClick event. Pseudo code:
If (column = Delivery Order Receipt)
{
LoadPDF()
}
Else if (column = Customer Delivery Location)
{
LaunchDeliveryWindow()
}
This seems a little sloppy to me. Especially if at some point in time the program needs to be expanded to include unique rightclick actions, or something along those lines. Then the code would basically have to be duplicated. Is there a better approach? What about having a class, maybe ColumnActionType, that defines what actions should be associated with a column?
In my opinion, below is decent way of implementing it. Especially if there aren't very many columns/actions. However it really depends on the situation as DonBoitnott pointed out in his comment.
private enum ActionType
{
CellRightClick,
CellDoubleClick
// add as you need them
}
private void dgv_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0)
{
DataGridViewColumn selectedColumn = this.dgv[e.ColumnIndex, e.RowIndex].OwningColumn;
this.PerformActionOnColumn(ActionType.CellDoubleClick, selectedColumn.Name);
}
}
private void PerformActionOnColumn(ActionType action, string columnName)
{
switch (columnName)
{
case "col_One":
switch (action)
{
case ActionType.CellRightClick:
// right click actions for col_One
break;
case ActionType.CellDoubleClick:
// double click actions for col_One
break;
}
break;
case "col_Two":
switch (action)
{
case ActionType.CellRightClick:
// right click actions for col_Two
break;
case ActionType.CellDoubleClick:
// double click actions for col_Two
break;
}
break;
}
}
Where dgv is the DataGridView at hand. I put this in the CellDoubleClick event, but you can put it in any event that uses the DataGridViewCellEventArgs, or really any event where you can access the currently selected column.
private void dgGridView_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == dgGridView.Columns["dgcCustomer"].Index && e.RowIndex >= 0)
{
DataGridViewRow selectedRow = dgGridView.Rows[e.RowIndex];
.
.
.
}
}
Where dgGridView is the DataGridView object, "dgcCustomer" is a column in the DataGridView, and the dotted continuation lines is the response to that click event.
I think using the switch statement would be better
switch (column) {
case "Delivery Order Receipt":
LoadPDF();
break;
case "Customer Delivery Location":
LaunchDeliveryWindow();
break;
default:
break;
}

How can I change what happens when "enter" key is pressed on a DataGridView?

when I am editing a cell and press enter the next row is automatically selected, I want to stay with the current row... I want to happen nothing except the EndEdit.
I have this:
private void dtgProductos_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
dtgProductos[e.ColumnIndex, e.RowIndex].Selected = true; //this line is not working
var index = dtgProductos.SelectedRows[0].Cells.IndexOf(dtgProductos.SelectedRows[0].Cells[e.ColumnIndex]);
switch (index)
{
case 2:
{
dtgProductos.SelectedRows[0].Cells[4].Selected = true;
dtgProductos.BeginEdit(true);
}
break;
case 4:
{
dtgProductos.SelectedRows[0].Cells[5].Selected = true;
dtgProductos.BeginEdit(true);
}
break;
case 5:
{
btnAddProduct.Focus();
}
break;
default:
break;
}
}
so when I edit a row that is not the last one I get this error:
Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function.
I think you'll need to override ProcessEnterKey to not advance focus to the next row.
Maybe this thread will help.

Categories