Different functionalities of button[] at each click on a particular button - c#

I have an array of button created dynamically, suppose 8 buttons, what I want is that when I click a particular button its background picture is changed and the name of button is stored in a linked list. When I click the same button again the background picture goes back to the original and the button name is deleted from linked list. Now I am able to do the first part, the second click is not working as I want it to.
Basically it's a datastructures project (shopping store) therefore I am using linked list, I have a linked list whose content is displayed through picture boxes[] and labels. Here what i am trying to do is when I click the picture box, the content of that particular node is added to a new linked list (added to the cart) and when I click on the picturebox again that particular item is deleted from the linked list (removed from the cart). Clicking it for the first time it is doing what i want it to do but the second click is not really working.
It's a datastructures project therefore I can't really use any built in classes for linked list, I had to write all methods myself and I did and they work.
cb[i].Click += (sender, e)=>{
if (flag == 0) {
// Console.WriteLine(obj.Retrieve(index).NodeContent);
// Console.WriteLine(obj.Retrieve(index).number);
inv.Add(obj.Retrieve(index).NodeContent, obj.Retrieve(index).number);
bill += Convert.ToInt32(obj.Retrieve(index).number);
cb[index].Image = Image.FromFile(#"F:\uni work\3rd semester\project images\rcart.jpg");
flag++;
}
else if (flag == 1)
{
// Console.WriteLine(bill);
bill -= Convert.ToInt32(obj.Retrieve(index).number);
// Console.WriteLine(bill);
inv.Delete(index);
cb[index].Image = Image.FromFile(#"F:\uni work\3rd semester\project images\cart.png");
flag--;
}

Since you are using a LinkedList it does have a Contains Method and a Remove Method that take a string. You haven't specified exactly what your problem is this should work. When you assign images to a control you loose the information that tells you what Image it is.
public partial class Form1 : Form
{
LinkedList<String> myList = new LinkedList<String>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 8; i++)
{
Button b = new Button() { Height = 30, Width = 70, Location = new Point(i, 50 * i),Name = "NewButton" + (i + 1).ToString() , Tag=i};
b.Click += b_Click;
this.Controls.Add(b);
}
}
void b_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
if(myList.Contains(b.Name)) //Check if button is in the List then Change Picture and remove
{
b.BackgroundImage = Properties.Resources.Peg_Blue;
myList.Remove(b.Name);
}
else
{
b.BackgroundImage = Properties.Resources.Peg_Red;
myList.AddLast(b.Name);
}
}
}

Why not create a class for each button, containing the two images and switch between them on each click?

Related

How to create a dynamic list of buttons on MainPage in Xamarin.Forms?

I'm creating an application to scan barcode tickets. When you start the app a list of available shows has to be shown on the screen. To get all the available shows I'm using a webservice which returns me a List<Event>. How do I create a list of buttons with each button representing a show/event from inside the xaml.cs? When clicking the button a new page will be shown where the user can scan the tickets from that show. I'm pretty new to Xamarin.Forms and I quite don't understand how to use the paging/content views. I already searched a lot but the closest to what I need was this: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/get-started-with-xaml?tabs=vswin
Unfortunatly it only shows how to add a certain amount of controls. And not a dynamicly generated amount.
Many thanks in advance!
In xaml insert a stacklayout where you want your buttons to appear. Remember you can also play whith its Orientation and Spacing properties. So:
<StackLayout x:Name="MyButtons"/>
Then in code-behind generate your dinamic buttons list. Put the code in constructor AFTER InitializeComponent(); or somewhere else:
var myList = new List<*Event or something*>(); //your list here
MyButtons.Children.Clear(); //just in case so you can call this code several times np..
foreach (var item in myList)
{
var btn = new Button()
{
Text = item.*your property*, //Whatever prop you wonna put as title;
StyleId = item.*your ID property* //use a property from event as id to be passed to handler
};
btn.Clicked += OnDynamicBtnClicked;
MyButtons.Children.Add(btn);
}
Add a handler:
private void OnDynamicBtnClicked(object sender, EventArgs e)
{
var myBtn = sender as Button;
// who called me?
var myId = myBtn.StyleId; //this was set during dynamic creation
//do you stuff upon is
switch (myId)
{
case "1": //or other value you might have set as id
//todo
break;
default:
//todo
break;
}
}

Can't read value from dynamically generated Radio Button list

I'm trying to do this:
read multiple values from Windows registry (works). This looks like
\HKLM\...\Server1
int serverid 1
string serverName "SRVSQL01"
int serverport 1433
string database "MyDatabase1"
\HKLM\...\Server2
dword/int serverid 2
regsz/string serverName "SRVSQL02"
dword/int serverport 1433
regsz/string database "MyDatabase2"
The number of servers can vary.
List items. I can read the values from the registry, this works fine
Add values to multiple instances of a C# class (works)
I created a class "SQLServer" with 4 variables/values, as displayed above.
Then I create an array of multiple instances of this class, for example if there are 4 servers listed in the registry, I generate an array with length 4 and add the value of each server to its own entity of this class.
public class RegSQLListItem
{
public int MSSSQLID;
public string MSSQLServer;
public int MSSQLPort;
public string MSSQLDatabase;
}
display the list in a new Form by generating radio buttons, based on the number of "items" in an array.
I found some code here to dynamically generate a list of radio buttons with labels: https://msdn.microsoft.com/en-us/library/dwafxk44(v=vs.90).aspx
// Generate form
int ProjectCounter = (RegProjectRoot.GetSubKeyNames()).Count();
// other code
RadioButton[] radioButtons = new RadioButton[ProjectCounter];
for (int i = 0; i < ProjectCounter; ++i)
{
radioButtons[i] = new RadioButton();
radioButtons[i].TabIndex = i + 1;
radioButtons[i].Name = ProjectListItem[i].MSSQLDatabase;
radioButtons[i].Text = ProjectListItem[i].MSSQLDatabase;
radioButtons[i].Location = new System.Drawing.Point(10, 10 + i * 20);
this.Controls.Add(radioButtons[i]);
}
How can I capture which radio button is selected and how to I transfer the corresponding value to another routine in my program?
I'm particularly interested in clicking an "OK" button to capture the value of the currently active radio button and so select which database I want to connect to.
Is this a correct way to do this at all or is there an easier way?
I'm new to C#, so I'm not that familiar with the possibilities.
You can do this in two ways.
1. Add event handler like the following:
for (int i = 0; i < ProjectCounter; ++i)
{
radioButtons[i] = new RadioButton();
radioButtons[i].TabIndex = i + 1;
radioButtons[i].Name = "ProjectListItem[i].MSSQLDatabase";
radioButtons[i].Text = "ProjectListItem[i].MSSQLDatabase";
radioButtons[i].Location = new System.Drawing.Point(10, 10 + i * 20);
radioButtons[i].CheckedChanged += new EventHandler(rdo_CheckedChanged);
this.Controls.Add(radioButtons[i]);
}
And the Handler rdo_CheckedChanged will defined like the following:
private static void rdo_CheckedChanged(object sender, EventArgs e)
{
RadioButton rdoButton = sender as RadioButton;
if (rdoButton.Checked)
{
// procced the button is checked
}
}
2. Iterate through controls of type RadioButton
You can iterate through the controls and identify the selected radio button by using the following code:
foreach (RadioButton rdo in this.Controls.OfType<RadioButton>())
{
if (rdo.Checked)
{
// this is checked radio button
// Proceed with your code
}
}

Reference and store Data from Dynamically created Controls?

I have a problem I've been looking into for a few days now, I just can't think of a logical way of doing what I want.
I have an app which has a task list. It starts of with 3 controls: a textbox, datetimepicker and a PictureBox which changes image on click. The user can then press an image which will add another row of controls below (It gets the properties of the dynamic controls from the controls already created):
https://www.dropbox.com/s/o2pub6orww24w25/tasklist.png (This is a screenshot to make it clearer)
Now what I want to do is save the values from each of the rows (A row being defined as: Textbox, Date, Status) into an SQLite DB.
For the first row it is easy, because that has a unique design name (and is a 'static' control).
However, the problem hits when I attempt to save values from the dynamic controls:
Problem a) I cannot reference the dynamic control because 'It does not Exist in the current Context'. -The function for creating the controls has a public access modifier so I thought that should do the trick? -It didn't. I've also tried:Panel1.pb.blah but it still didn't recognize the control?
Problem b) How can I tell my program that each row is a new set of data? In other words, how can I run a new insert command for each row? -I thought of doing this as a for-each-textbox loop, however would that not just pick up the first dynamic date everytime?
I've also thought of using the tag property and setting it to the counter variable, to group the controls in the row. (The counter being an integer which increments every time a new row is added.) However I cannot do that because the picture box uses the tag property as part of its function to change image on click (Changes multiple times).
Code:
Adding the Controls:
public void pictureBox1_Click(object sender, EventArgs e)
{
//TextBox Control
int tbh = tasktb.Location.Y + (counter*25);
int tbsh = tasktb.Size.Height;
int tbsw = tasktb.Size.Width;
TextBox tb = new TextBox();
tb.Location = new Point(9, tbh);
tb.Size = new System.Drawing.Size(tbsw, tbsh);
tb.Tag = counter.ToString();
//Date Time Control
int dth = duedatedb.Location.Y + (counter * 25);
int dtsh = duedatedb.Size.Height;
int dtsw = duedatedb.Size.Width;
DateTimePicker dtp = new DateTimePicker();
dtp.Location = new Point(300, dth);
dtp.Size = new Size(dtsw, dtsh);
dtp.Format = System.Windows.Forms.DateTimePickerFormat.Short;
//Picture Box Control
int stsh = status.Location.Y + (counter * 25);
int stssh = status.Size.Height;
int stssw = status.Size.Width;
PictureBox pb = new PictureBox();
pb.Location = new Point(429, stsh);
pb.Size = new Size(stssw, stssh);
pb.Image = Red;
pb.Click += new System.EventHandler(pb_Click);
panel1.Controls.Add(tb);
panel1.Controls.Add(dtp);
panel1.Controls.Add(pb);
++counter;
}
Trying to Reference the control: (For purposes of changing the image on click) [Found the Control.Find function from researching this in the MSDN Website]
public void pb_Click(object sender, EventArgs e)
{
PictureBox pb = (panel1.Controls.Find("pb",false));
if (pb.Image == Red) { pb.Image = Orange; status.Tag = "Orange"; }
else if (pb.Image == Orange) { pb.Image = green; status.Tag = "Green"; }
else if (pb.Image == green) { pb.Image = Red; status.Tag = "Red"; }
}
The essential problem here is Problem a, if you guys could see where I have gone wrong with that, I'd be able to go away and attempt to write some code to get around problem b.
(I have included Problem b in this for your suggestions on the best way to do this. -At the moment I have no clue!)
Thank you for any help received! It really is appreciated!
ControlCollection.Find looks for a control with the specified name, and you haven't set any. The variable names in your code aren't related. So, either:
pb.Name = "pb";
But that would mean you'd eventually have several items with the same name. So, seeing how you want to change the picture of the clicked PictureBox, just do this:
public void pb_Click(object sender, EventArgs e)
{
PictureBox pb = (PictureBox)sender;
if (pb.Image == Red) { pb.Image = Orange; status.Tag = "Orange"; }
else if (pb.Image == Orange) { pb.Image = green; status.Tag = "Green"; }
else if (pb.Image == green) { pb.Image = Red; status.Tag = "Red"; }
}
The sender argument always contains a reference to whichever control raised the event, in this case whichever picturebox was clicked!
Edit: As for your other question, I assume you'll need to do stuff to the controls later on, so I suggest you store a reference to all of them (or at least the ones you need), something like this:
// helper class
private class Entry
{
public TextBox TextBox { get; private set; }
public DateTimePicker DateTimePicker { get; private set; }
public PictureBox PictureBox { get; private set; }
public Entry( TextBox tb, DateTimePicker dtp, PictureBox pb )
{
this.TextBox = tb;
this.DateTimePicker = dtp;
this.PictureBox = pb;
}
}
// member field
private List<Entry> m_Entries = new List<Entry>();
// at the end of pictureBox1_Click
public void pictureBox1_Click(object sender, EventArgs e)
{
....
m_Entries.Add( new Entry( tb, dtp, pb ) );
}
Then you can use the items in that list to interact with your rows. You might also want to add an index, or a reference to whatever the original data structure is. Also, you might want to think about if you really should be creating the controls yourself like that or actually use some kind of table/grid control to host them!
Or perhaps just wrap up all those controls in a single UserControl, with logic included and all!

How to change checkbox text in checkboxlist? I tried but got error message

I work on windows application. It has one form in application which displays check boxes in check box list, here is the screen shot of form
It's single from of my application which i display in different languages And also my windows application is made in multiple languages Like English, German, Japanese etc..
My problem is that how to display translated text of check box in check box list
Here is my code :
this.checkedListBox1.FormattingEnabled = true;
this.checkedListBox1.Items.AddRange(new object[] {
"Select All",
"Amplitude1",
"Amplitude2",
"Amplitude3",
"Amplitude4",
"Amplitude5",
"Amplitude6",
"Amplitude7"});
this.checkedListBox1.Location = new System.Drawing.Point(96, 55);
this.checkedListBox1.Name = "checkedListBox1";
this.checkedListBox1.Size = new System.Drawing.Size(123, 124);
this.checkedListBox1.TabIndex = 8;
this.checkedListBox1.SelectedIndexChanged += new System.EventHandler(this.ckbselectall_CheckedChanged);
I made a single file to translate text of form, i put that code below where LCheckBox is my file from where i translate the text of check box in check box list
this.checkedListBox1.FormattingEnabled = true;
this.checkedListBox1.Items.AddRange(new object[] {
LCheckBox.SELECTALL,
LCheckBox.Amplitude1,
LCheckBox.Amplitude2,
LCheckBox.Amplitude3,
LCheckBox.Amplitude4,
LCheckBox.Amplitude5,
LCheckBox.Amplitude6,
LCheckBox.Amplitude7});
this.checkedListBox1.Location = new System.Drawing.Point(96, 55);
this.checkedListBox1.Name = "checkedListBox1";
this.checkedListBox1.Size = new System.Drawing.Size(123, 124);
this.checkedListBox1.TabIndex = 8;
this.checkedListBox1.SelectedIndexChanged += new System.EventHandler(this.ckbselectall_CheckedChanged);
But it gives me some error message
you can ask for the language at the begining and then create the checkbox list depending on the language. u can use different if cases for each language
In code I just use the items collection to modify the desired item.
So lets say you have a form with a button on it. When the button is clicked
you want to add one to all the items in the list, then the code to do that
would look as found below assuming that the listbox was named "_list" and
the button was named "_button."
private void FillList()
{
_list.BeginUpdate();
_list.Items.Clear();
for(int i =0 ; i <=9; i++)
_list.Items.Add(i);
_list.EndUpdate();
}
private void _button_Click(object sender, System.EventArgs e)
{
_list.BeginUpdate();
ListBox.ObjectCollection items = _list.Items;
int count = items.Count;
for(int i = 0; i < count; i++)
{
int integerListItem = (int)items[i];
integerListItem ++;
// --- Update The Item
items[i] = integerListItem;
}
_list.EndUpdate();
}

Customising the a GridViewTextBoxColumn to allow me to have a button at Cell Edit Time

I have created a Custom GridViewTextBoxColumn to handle the following:
1) Display as a Normal TextboxColumn when not in EditMode (problem area)
1) In Edit Mode, I add AutoComplete to the Cell to prompt the user for a list of items
2) To click an ellipse button I have placed to the left of the textbox to browse (Open's a Form with a Grid of Items with more columns)
I have added all no problem and I can dynamically add the AutoComplte Source in the BeginEdit even on the cell (Or I can add it in the CreateChildElements merthod in the AutoCompleteTextBoxCellElement)
So what happens is the following:
My class is this:
public class AutoCompleteTextBoxCell : GridDataCellElement
{
public AutoCompleteTextBoxCell(GridViewColumn column, GridRowElement row)
: base(column, row)
{
}
}
Then I add this method to add the element, textbox
protected override void CreateChildElements()
{
txtStockCode = new RadTextBoxElement();
this.Children.Add(txtStockCode);
LoadData("Code"); //Adding Auto Complete in this event
}
I also add this so that I can arrange the elements in the cell.
protected override SizeF ArrangeOverride(SizeF finalSize)
{
RectangleF rect = GetClientRectangle(finalSize);
RectangleF rectEdit = new RectangleF(rect.X, rect.Y, rect.Width - (32 + 1), rect.Height);
RectangleF rectButton = new RectangleF(rectEdit.Right + 1, rectEdit.Y, 32, rect.Height);
if (this.Children.Count >= 2)
{
this.Children[0].Arrange(rectEdit);
this.Children[1].Arrange(rectButton);
}
else
{
rectEdit = new RectangleF(rect.X, rect.Y, rect.Width, rect.Height);
this.Children[0].Arrange(rectEdit);
}
return finalSize;
}
Then Back on the Grid, I do the following:
enter code here
private void grdMain_CellBeginEdit(object sender, GridViewCellCancelEventArgs e)
{
if (e.Column.Name == "colItem")
{
RadButtonElement btnMore = new RadButtonElement();
btnMore.Text = "...";
btnMore.Click += new EventHandler(btnMore_Click);
grdMain.CurrentCell.Children.Add(btnMore);
}
}
This adds my button so that I can launch the browse form at the Edit Mode of the cell.
The in the EndEdit Event, I remove the button.
private void grdMain_CellEndEdit(object sender, GridViewCellEventArgs e)
{
if (e.Column.Name == "colStock")
{
if (this.grdMain.CurrentCell.Children.Count <= 2) //This might be 1 or 2
{
if (grdMain.CurrentCell.Children.Count == 2) // If its two, I need to remove the button
{
if (grdMain.CurrentCell.Children[1] is RadButtonElement)
{
this.grdMain.CurrentCell.Children.RemoveAt(1);
}
//If one, I do nothing for the moment. -- I think.
}
}
}
}
All is fine accept for one problem.
When the cell is added I assume it will go back to behave just like a normal textbox column (due to my inheritance), but its not, the text is hidden - well I cant see it.
When I click the cell to enter edit mode, the text i entered is there.
I do think this is a problem with what I am trying to achieve, I think its an issue with the chain of events.
Can any one tell me why the text is not showing when the cell is not in edit mode?
Regards
John

Categories

Resources