PointerEntered is triggered when the mouse pointer enters a MenuFlyoutItem, but not when it enters a MenuFlyoutSubItem. What event is triggered when the mouse pointer enters a MenuflyoutSubItem element? I want to capture the text property of the MenuflyoutSubItem element in an event handler when the mouse pointer enters it. (The reason I can't rely on the tapped event is because even just hovering over the MenuFlyoutSubItem opens its contained menu items.) Here is the code:
public DynamicMenuTestPage()
{
InitializeComponent();
for (int i = 0; i < 5; i++)
{
MenuFlyoutSubItem myItem = new MenuFlyoutSubItem();
myItem.Text = "Item" + i;
myItem.PointerEntered += MyItem_PointerEntered;
MyMenu.Items.Add(myItem);
for (int j = 0; j < 4; j++)
{
MenuFlyoutItem mySubItem = new MenuFlyoutItem();
mySubItem.Text = "SubItem" + j;
mySubItem.PointerEntered += mySubItem_PointerEntered;
myItem.Items.Add(mySubItem);
}
}
}
private void MyItem_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
// This does not work. It is not triggered when the mouse pointer enters the menu flyout subitem.
MenuFlyoutSubItem test = sender as MenuFlyoutSubItem;
var menuFlyoutSubItemText = test.Text;
}
private void mySubItem_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{ //This works. It is triggered when the mouse pointer enters the menu flyout item.
MenuFlyoutItem test = sender as MenuFlyoutItem;
var menuFlyoutItemText = test.Text;
}
Here is a screenshot of the menu. When I hover over Item0, circled in red, the submenu opens. What event will enable me to capture the text, "Item0"?
It seems the MenuFlyoutSubItem doesn't fire the PointerEntered RoutedEvents, you can wire an event handler for this RoutedEvents.
myItem.AddHandler(PointerEnteredEvent, new PointerEventHandler(PointEnterHandler), true);
So your code will be like this:
public MainPage()
{
this.InitializeComponent();
for (int i = 0; i < 5; i++)
{
MenuFlyoutSubItem myItem = new MenuFlyoutSubItem();
myItem.Text = "Item" + i;
myItem.AddHandler(PointerEnteredEvent, new PointerEventHandler(PointEnterHandler), true);
MyMenu.Items.Add(myItem);
for (int j = 0; j < 4; j++)
{
MenuFlyoutItem mySubItem = new MenuFlyoutItem();
mySubItem.Text = "SubItem" + j;
mySubItem.PointerEntered += mySubItem_PointerEntered;
myItem.Items.Add(mySubItem);
}
}
}
private void PointEnterHandler(object sender, PointerRoutedEventArgs e)
{
MenuFlyoutSubItem test = sender as MenuFlyoutSubItem;
var menuFlyoutSubItemText = test.Text;
}
private void mySubItem_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{ //This works. It is triggered when the mouse pointer enters the menu flyout item.
MenuFlyoutItem test = sender as MenuFlyoutItem;
var menuFlyoutItemText = test.Text;
}
Related
I have dynamically created a list of buttons and set it to the form. After clicking one of them, the very next button to it will appear as selected.
Is it possible to deselect all controls dynamically created in a form? Particularly, can I, somehow, deselect that button after clicking the one before it?
private void GenerateButton()
{
for (int i = 1; i <= 15; ++i)
{
for (int j = 1; j <= 25; ++j)
{
Button button = new Button();
button.Location = p;
button.Size = size;
button.BackColor = Color.RoyalBlue;
button.Padding = pad;
button.Click += new EventHandler(button_Click);
this.Controls.Add(button);
p.X += 23;
}
p.Y += 23;
p.X = 0;
}
}
protected void button_Click(object sender, EventArgs e)
{
Button but = sender as Button;
but.Enabled = false;
but.BackColor = Color.LightGray;
}
You might try this method, which will select the next button in the form, after clicking on a button. You need to attach this button event handler to all your buttons. The order of buttons is determined by their order in the form Controls list. If you want a specific order, you will need to use LINQ to sort Controls by their TabOrder property and ensure your TabOrder is set properly
private void button_Click(object sender, EventArgs e)
{
var btn = (Control)sender;
btn.Enabled = false;
btn.BackColor = Color.LightGray;
// Where is this button in the form?
var indexOfThisButton = this.Controls.IndexOf(btn);
// Find next button index
for (int i = indexOfThisButton+1; i < this.Controls.Count; i ++)
{
// If it's a button, select it
if (this.Controls[i] is Button)
{
this.Controls[i].Select();
return;
}
}
// If we got down here we have got to the end of the controls list, start again
for (int i = 0; i < this.Controls.Count; i++)
{
// If it's a button, select it
if (this.Controls[i] is Button)
{
this.Controls[i].Select();
return;
}
}
}
I am currently experimenting in WPF and just created a UniformGrid with 800 buttons which are created in a for loop. All buttons have their own names and share the same click event.
What I want to do now is the following: I want to click the first button (rect0) to change the color of this button and the next one (rect1).
I am totally stuck right now because everything I write into the click event refers to the button I clicked.
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 800; i++)
{
Button BTN_rect = new Button()
{
Name = "rect" + i,
Background = Brushes.White,
};
BTN_rect.Click += BTN_rect_Click;
Uniform.Children.Add(BTN_rect);
}
}
private void BTN_rect_Click(object sender, RoutedEventArgs e)
{
Button BTN_rect = sender as Button;
BTN_rect.Background = Brushes.Red;
MessageBox.Show(BTN_rect.Name);
}
There are a load of ways to do this.
I took a shortcut and put just 9 buttons in a stackpanel, otherwise the same.
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 8; i++)
{
Button BTN_rect = new Button()
{
Name = "rect" + i,
Content =Name,
Tag = i,
Background = Brushes.White,
};
BTN_rect.Click += BTN_rect_Click;
sp.Children.Add(BTN_rect);
}
}
private void BTN_rect_Click(object sender, RoutedEventArgs e)
{
Button current = sender as Button;
current.Background = Brushes.Red;
string targetName = $"rect{((int)current.Tag) + 1}";
Button nextButton = sp.Children.OfType<Button>().Where(x => x.Name == targetName).SingleOrDefault();
nextButton.Background = Brushes.Red;
}
Usually, you'd template data into repeated controls rather than add them in code, btw.
When btnAsset is double-clicked, it should go to allButton_Click.
But it only goes in one click. how can I do that?
public void Add(MainForm frm)
{
this.form1 = frm;
for (int i = 0; i < 10; i++)
{
btnAsset[i] = new Button();
btnAsset[i].Tag = i;
btnAsset[i].Name = "Asset-" + i.ToString();
btnAsset[i].Width = 150;
btnAsset[i].Height = 120;
btnAsset[i].Visible = true;
btnAsset[i].BackColor = Color.GreenYellow;
form1.flowLayoutVideo.Controls.Add(btnAsset[i]);
btnAsset[i].DoubleClick += new EventHandler(allButton_Click);
}
}
should go here when double clicked
void allButton_Click(object sender, EventArgs e)
{
Button p = sender as Button;
if (p != null)
{
int i = (int)p.Tag;
MessageBox.Show((i + 1).ToString() + ". seçildi");
}
}
Look what the docs says about it:
By default, the ControlStyles.StandardClick and ControlStyles.StandardDoubleClick style bits are set to false for the Button control, and the DoubleClick event is not raised.
You can change this behaviour by creating your own button class deriving from Button and change the style bits.
I'd like to distinguish each of the Event handler.
(I have only one in my code below. I mean dynamic handler will be the best but, any kind of workarounds will be fine too.)
Please help me.
Thanks !
List<Button> VuttonList = new List<Button>();
private void Form1_Load(object sender, EventArgs e)
{
Button Vutton;
int Kount = 10;
for (int i = 0; i < Kount ; i++)
{
Vutton = new Button();
Vutton.Text = ( i + 1 ).ToString() ;
Vutton.Location = new Point(10, 24 * ( i + 1 ) );
Controls.Add( Vutton );
Vutton.Click += new EventHandler(Kommon);
VuttonList.Add( Vutton );
}
}
private void Kommon(object sender, EventArgs e)
{
MessageBox.Show( sender.ToString() );
}
One event handler is enough, you can cast the sender to Button and this way you know which button has been clicked. Also you can set Name property of buttons when you create them or assign Tag property of them and use it later.
for (int i = 0; i < Kount ; i++)
{
Vutton = new Button();
//...set properties
//Also add Name:
Vutton.Name = string.Format("Vutton{0}", i);
//Also you can add Tag
Vutton.Tag = i;
Controls.Add( Vutton );
Vutton.Click += new EventHandler(Kommon);
//... other stuff
}
Then you can use properties of button this way:
private void Kommon(object sender, EventArgs e)
{
var button = sender as Button;
//You can use button.Name or (int)button.Tag and ...
MessageBox.Show(button.Name);
}
Also to layout your buttons, you can use a FlowLayoutPanel or a TableLayoutPanel.
I have generated multiple buttons when I click on btnStart and I'd like to use booleans for each button to become true when it gets clicked so I can check the clicked buttons later on but I only know how to use the same event for every button
This is what I use to create the buttons (I left some unnecessary things out)
for (int i = 0; i < 5; i++) //I use this to horizontally generate buttons
{
for (int j = 0; j < 4; j++) //vertically generate buttons
{
Button btnNew = new Button();
btnNew.Name = "btnFlag" + i;
btnNew.Click += new EventHandler(btnNew_Click);
Controls.Add(btnNew);
aButtons.Add(btnNew); //this is a list I use to set random bgImages
}
}
Now when I click on btnNew it would do all the code set for the event btnNew_Click but I can't use btnFlag1_Click because it doesn't exist, does anyone know a way to create booleans for every buttons and set one to true when a specific button is being clicked
Like: when btnFlag1 gets clicked, turn boolean btn1 to true
and so on ..
Thank you in advance
When you are looping in your for statement you are assigning same event to all your methods.But the sender paramater of your method contains the reference of the button which is calling the specific event.
you can bind all the buttons to same event
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 4; j++)
{
Button btnNew = new Button();
btnNew.Name = "btnFlag" + i;
btnNew.Click += new EventHandler(btnNew_Click);
}
}
Then inside the button click new event you can select your specific sender and perform specific actions
public void btnNew_Click(object sender, ButtonEventArgs e)
{
Button b = sender as Button;
if( b.Name == "btnFlag0" )
{
//logic for your 1st btn
}
//.... repeat the same logic for others
}
You can use the sender argument in the event handler, which in fact is the specific Button which was clicked:
private void btnNew_Click(Object sender, EventArgs e)
{
Button btn = sender as Button;
string name = btn.Name;
}