highlighting the button that fired an event - c#

Consider a SilverLight project that has 31 hyperlinkbuttons. Those represent the days of the month. I'm using this code to highlight the hyperlinkbutton that respresent today's day.
var daynumberHyperButton = this.FindName("Day" + DateTime.Today.Day) as HyperlinkButton;
//Highlighting the day of the month
if (daynumberHyperButton != null)
{
daynumberHyperButton.Background = new SolidColorBrush(Colors.Gray);
}
Then if I click on this highlighted hyperlinkbutton, it will open a childwindow to write some report.
private void dayHyperLink_Click(object sender, RoutedEventArgs e)
{
//This will initite and show the report window
ReportWindow rapport = new ReportWindow();
rapport.Closed += new EventHandler(rapport_Closed);
rapport.Show();
}
When I close the childwindows by clicking the OK button, it changes the color of the hyperlinkbutton that was highlighted (todays day) because I'm using this code to do that:-
private void rapport_Closed(object sender, EventArgs e)
{
ReportWindow rapport = (ReportWindow)sender;
var daynumberHyperButton = this.FindName("Day" + DateTime.Today.Day) as HyperlinkButton;
if (rapport.UsersValue == "Röd" && rapport.DialogResult==true)
{
daynumberHyperButton.Background = new SolidColorBrush(Colors.Red);
}
else if (rapport.UsersValue == "Gul")
{
daynumberHyperButton.Background = new SolidColorBrush(Colors.Yellow);
}
else
{
daynumberHyperButton.Background = new SolidColorBrush(Colors.Green);
}
}
But if I click on any other hyperlinkbutton that is not highlighted, it still only change the color of the highlighted hyperlinkbutton. I know this because my rapport_Closed event has:
var daynumberHyperButton = this.FindName("Day" + DateTime.Today.Day) as HyperlinkButton;
How can I change the above code, which is part of my rapport_Closed event, so that it changes the color of the event firing (the one that opens the childwindow) hyperlinkbutton, no matter which hyperlinkbuttonis the one that fires the event?

Ok now i can say i've done it. Here is what i did if anyone have a similar problem.
In may Home.xaml.cs, i added a public property like this:-
public HyperlinkButton dayHyperLink { get; set; }
To the Click event i added this code:-
dayHyperLink = (HyperlinkButton)sender;
To the rapport_Closing event i changed the if statment to the code below:-
if (rapport.UsersValue == "Röd" && rapport.DialogResult == true)
{
dayHyperLink.Background = new SolidColorBrush(Colors.Red);
}
This made me feel happy ;)

Related

NavigationView change selected item using back button

I'm using a navigationview control in a UWP app, the thing is when I click the back button the focused element doesn't change to the item displayed in the contentframe. For example the clicked elements were camara, store, musica, then back button twice to display camara in the contentframe element, but musica still has the focus (blue rectangle)
private void FrameNavigated( object sender, NavigationEventArgs e )
{
var currentView = SystemNavigationManager.GetForCurrentView();
if ( ContentFrame.CanGoBack )
{
currentView.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
}
else
{
currentView.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
}
}
private void OnBackRequested( object sender, BackRequestedEventArgs e )
{
if ( ContentFrame.CanGoBack )
{
e.Handled = true;
PageStackEntry pageStackEntry = ContentFrame.BackStack.LastOrDefault();
ContentFrame.GoBack();
if ( pageStackEntry != null )
{
string nombre = pageStackEntry.SourcePageType.Name;
MenuItem item = subItemsMenu.FirstOrDefault(nom => nom.NombrePantalla.Equals(nombre));
navView.SelectedItem = item;
navView.Header = item.Encabezado;
}
}
}
Solved, using
NavigationViewExtensions.SetSelectedIndex(NavigationView, index); from Microsoft.Toolkit.Uwp.UI.Extensions 4.0.0, since 5.0.0 version is deprecated
I didn't see any problem in your code. Several ways may help to troubleshooting:
Debug and make sure MenuItem item is not null.
When back button is clicked, try select home or camera directly by your code
private void OnBackRequested( object sender, BackRequestedEventArgs e )
{
string nombre = "Camera";
MenuItem item = subItemsMenu.FirstOrDefault(nom => nom.NombrePantalla.Equals(nombre));
navView.SelectedItem = item;
}
Add SelectionChanged="nav_SelectionChanged" to the XAML and then check SelectionChanged
Post a simple app which can repro your problem

AppBar Button Changing icon dynamically

I have a button on appBar. When user clicks it, it should change the icon. It will either show the Map or List so it needs to toggle between those 2.
If I use the code below with icons Symbol.Play & Symbol.Stop it toggles perfectly.
But when I use Symbol.Map & Symbol.List it does not toggle properly. (On simulator at least.) It changes sometimes, but mostly stays the same icon.
Code:
private void MapToggle_Click(object sender, RoutedEventArgs e)
{
if (JobMap.Visibility != Visibility.Visible)
{
MapToggle.Icon = new SymbolIcon(Symbol.List);
MapToggle.Label = "List";
JobMap.Visibility = Visibility.Visible;
}
else
{
MapToggle.Icon = new SymbolIcon(Symbol.Map);
MapToggle.Label = "Map";
JobMap.Visibility = Visibility.Collapsed;
}
}
Binded to XAML
AppBarButton Name="MapToggle" Icon="Map" Click="MapToggle_Click" Label="Map"

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

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?

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!

Why can't I leave a TextBox using tab?

I have this code:
public static void AddDefaultTextFromTag(params TextBox[] textBoxes)
{
foreach (TextBox oTextBox in textBoxes)
{
bool isPasswordChar = oTextBox.UseSystemPasswordChar;
oTextBox.Enter += (sndr, evnt) =>
{
if (((TextBox)sndr).Text == ((TextBox)sndr).Tag.ToString())
{
((TextBox)sndr).Text = "";
((TextBox)sndr).UseSystemPasswordChar = isPasswordChar;
((TextBox)sndr).ForeColor = SystemColors.WindowText;
}
};
oTextBox.Leave += (sndr, evnt) =>
{
if (((TextBox)sndr).Text.Trim().Count() == 0)
{
((TextBox)sndr).UseSystemPasswordChar = false;
((TextBox)sndr).CharacterCasing = CharacterCasing.Normal;
((TextBox)sndr).Text = ((TextBox)sndr).Tag.ToString();
((TextBox)sndr).ForeColor = SystemColors.GrayText;
}
};
if (oTextBox.Text.Trim().Count() == 0)
{
oTextBox.UseSystemPasswordChar = false;
oTextBox.CharacterCasing = CharacterCasing.Normal;
oTextBox.Text = oTextBox.Tag.ToString();
oTextBox.ForeColor = SystemColors.GrayText;
}
}
}
But when the TextBox.UseSystemPasswordChar I input in this method's parameter is true and it's TextBox.Text property is empty, the TextBox can't leave using a Tab button on the keyboard, only a MouseClick can be used to lose the focus of that TextBox.
Why is this happening?
My code is in C#, framework 4, build in VS2010 Pro, project is in WinForms.
I use a TextBox from the VS ToolBox.
Please help. Thanks in advance.
The reason you can't leave the textbox is because you are changing the CharacterCasing property in the textbox.
Not sure why it works like this, but it has happened to me before, what I ended up doing was capture the keypress event, and if it was a letter I'd switch it to it's uppercase value. It's not optimal, but it works
I did something similar to this (writing it from the top of my head, but it should work):
void YourTextbox_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsLetter(e.KeyChar))
{
if (this.CharacterCasing == CharacterCasing.Upper && char.IsLower(e.KeyChar))
{
this.Text = this.Text.Insert(this.SelectionStart, char.ToUpper(e.KeyChar) + string.Empty);
this.SelectionStart++;
e.Handled = true;
}
else if (this.CharacterCasing == System.Windows.Forms.CharacterCasing.Lower && char.IsUpper(e.KeyChar))
{
this.Text = this.Text.Insert(this.SelectionStart, char.ToLower(e.KeyChar) + string.Empty);
this.SelectionStart++;
e.Handled = true;
}
}
}
You also should use the new keyword to "override" (I know that's not the right term here) the Character casing, so it doesn't do it's own thing
public new CharacterCasing CharacterCasing { get; set; }
The code basically checks if the pressed key is a letter, then, if it's marked as Upper, and the char is lower, replaces it with it's upper version (in the position of the cursor) then moves the cursor to the next part, and Viceversa (toLower)
NOTE:
This code will have may (should) have some trouble if the user has more than one character selected (SelectionLenght > 0), if you want to keep the normal Textbox functionality, you should delete all the selected characters
So I set up a WinForms app, drew two textboxes, set one to UseSystemPasswordChar=true then set it up like so:
private void Form1_Load(object sender, EventArgs e)
{
textBox2.Tag = "test2";
textBox1.Tag = "test1";
TextBox[] tb = { textBox1, textBox2 };
AddDefaultTextFromTag(tb);
}
Your function works fine and I have no problems tabbing through the controls on the form no matter what the textboxes contain. (added a button also that does nothing for tabbing test) so... no repro unless my test setup is not valid
What I found in the answer of this post was the solution for me. Instead of setting UseSystemPasswordChar to true and then to false, you can set PasswordChar to '●' and then to '\0' to have normal text. You should not set the UseSystemPasswordChar because it has precedence over PasswordChar.

Categories

Resources