Gtk# OnButtonPressEvent is not working - c#

I am pretty new to Gtk#, so please be patient. I want to create my own widget which will have two functions: draw what you want, and report if user clicked at this widget.
My code in method:
protected override bool OnExposeEvent (Gdk.EventExpose args)
{
// this works!
}
is fully working, but the code in following method:
protected override bool OnButtonPressEvent (Gdk.EventButton ev)
{
// this is not working at all :-(
Console.WriteLine("test!");
return base.OnButtonPressEvent (ev);
}
is not working. Both methods are some responses on events, so why OnButtonPressEvent is not called when I click at widget??
I have another widget which inherits from Table, but Buttons in Table works well, so why is there this problem?
Thanks in advance...

You have to create a signal to your button like this:
Button button = new Button();
button.Clicked += Button_Clicked;
private void Button_Clicked(object sender, EventArgs e)
{
//some stuff
}
It will work correctly. This is the way you must use Button widget. Sometimes it's depending how you layout your app, some widgets can be on your button and it can make unwanted behaviors.

You want to use Button Clicked signal instead of Button Pressed. That's what I use with all of my buttons and it works as expected.

Related

Button isn't disabling after I click it

I have created a button that resets a textbox value to the default value, as shown:
<Button x:Name="DefaultButton"
Grid.Row="0"
Grid.Column="3"
Click="OnDefaultClicked">
Here is the Click method:
private void OnDefaultClicked(object sender, RoutedEventArgs e)
{
DefaultButton.IsEnabled = false;
displayedData = defaultData;
//rest of method code
}
When I click the button, the data resets to its default value automatically, but the button does not get disabled until I click it a second time. I am not sure why this is happening.
I could implement the IsEnabled property in the xaml code and bind it to a method that determines whether the button should be enabled based on the value of displayedData, but since the button is not re-enabled/disabled anywhere else in my application or used for any other purpose, this seems kind of like overkill... as far as I know, the Click event should be able to handle this alone. Regardless, my main problem is that I just don't understand why the button wouldn't get disabled until the 2nd click since the OnDefaultClicked method explicitly states it should be disabled when clicked.
Am I missing something?
Turns out the problem was in the rest of my code. The snippet posted above worked perfectly fine. I realized I had created a method that re-enables the button when the text in the box changes, to allow the user to again reset it to default after making a change. So when the default button is clicked, the text in the box changes and therefore both the OnTextChanged and OnDefaultClicked methods are triggered, which causes simultaneous enabling and disabling of the button.
Here's how I fixed it:
private bool DefaultClicked;
private void OnDefaultClicked(object sender, RoutedEventArgs e)
{
DefaultButton.IsEnabled = false;
DefaultClicked = true;
displayedData = defaultData;
//rest of method code
}
private void OnTextChanged(object sender, RoutedEventArgs e)
{
if(!DefaultClicked)
{
DefaultButton.IsEnabled = true;
}
DefaultClicked = false;
//rest of method code
}

How to react to a onclick in an ultragrid

I have code that creates an UltraGrid with a column that has the ColumnStyle.Button as it's style.
private void Grid_InitializeLayout(object sender, InitializeLayoutEventArgs e){
Grid.ResetEmptySelectedAppearance();
var column = Grid.SetColumn("Draw Lines", "Draw Lines", 30);
column.Style = ColumnStyle.Button;
Grid.HideOtherColumns();
}
Now I would like too make it react to being clicked on. I have found this but it does not show me how to bind the variable, usually I can either double click in the visual studio editor (but in this case this only directs me too the Grid_InitializeLayout) or I can go the the item in question and add the function to an OnClick variable, but this one doesn't exist.
private void Grid_InitializeRow(object sender, InitializeRowEventArgs e)
var buttoncell= e.Row.Cells["Draw Lines"];
//something here?
this is what I want to call
private void OnDrawLine(object sender, Infragistics.Win.UltraWinGrid.CellEventArgs e)
{
Debug.Print("test test");
}
It's probably something trivial but I'm stuck.
The UltraGrid responds to clicks on a cell button as explained in the link posted using an event called ClickCellButton. You need to subscribe to this grid event in the usual ways. (Designer or code doesn't matter)
private void Grid_ClickCellButton(object sender, ClickCellEventArgs e)
{
// Check if the click happens on the required column
if (e.Cell.Column.Key == "Draw Lines")
{
... your code ...
}
}

Simple ON/OFF toggle button with image

I'm working on a WinForms project where I'm trying to create an ON/OFF toggle button that uses two separate images (both located in project resources) for both the "ON" setting, and the "OFF" setting.
Based on what I've found online, I've used a CheckBox with its appearance set to "Button".
Here is the code I've got so far for my button:
private void ToggleButton_CheckedChanged(object sender, EventArgs e)
{
if (ToggleButton.Checked)
{
ToggleButton.BackgroundImage.Equals(Properties.Resources.ToggleButton_ON);
}
else
{
ToggleButton.BackgroundImage.Equals(Properties.Resources.ToggleButton_OFF);
}
}
For some reason nothing happens when I click on the button, and I'm not sure what I've done wrong here.
Basically, I'd like the background image to cycle back and fourth between ToggleButton_ON and ToggleButton_OFF when the user clicks on the button.
Change your code to:
private void ToggleButton_CheckedChanged(object sender, EventArgs e)
{
if (ToggleButton.Checked)
ToggleButton.BackgroundImage = Properties.Resources.ToggleButton_ON;
else
ToggleButton.BackgroundImage = Properties.Resources.ToggleButton_OFF;
}
The .Equals is for checking equality which you can override in your own classes.

How do I make buttons do the same thing?

I just started programming, and I want to use WinForms to make multiple buttons that you can click on to change from white to lime-green and back to white. I have done this for one button:
private void button1_Click(object sender, EventArgs e)
{
if (button1.BackColor != Color.Lime)
{
button1.BackColor = Color.Lime;
}
else
{
button1.BackColor = Color.White;
}
}
Now I could copy and paste that for all of the buttons, but I know that is inefficient; and if I use winforms to reference button1 on button2, it will just change the color of button1 (obviously).
So, do I need to use a helper method, new class, or something else? What would that look like?
There are a couple of approaches. One might be to create a common function which the different buttons call:
private void button1_Click(object sender, EventArgs e)
{
ChangeColor(button1);
}
private void ChangeColor(Button button)
{
if (button.BackColor != Color.Lime)
button.BackColor = Color.Lime;
else
button.BackColor = Color.White;
}
Then each button handler can use that same function call.
Or, if all of these buttons will always ever do exactly the same thing, then you can use one click handler function for all of them. In this case what you'd need to do is determine which button invoked the handler (whereas you're currently referencing button1 directly) so that you know which one to change. The sender object passed into the handler function is actually a reference to the form element which invoked the handler. All you need to do is cast it:
private void button_Click(object sender, EventArgs e)
{
var button = (Button)sender;
if (button.BackColor != Color.Lime)
button.BackColor = Color.Lime;
else
button.BackColor = Color.White;
}
So first the handler grabs a reference to the button which invoked it, then runs the logic on that button. Note also how I made the name of the handler function slightly more generic. Now you'd go to the form designer and set button_Click as the click handler for all of the buttons which should invoke this.
You do this the exact same way you'd do it for any C# class. You derive your own class and customize the base class behavior. Every event has a corresponding OnXxxx() method that you can override.
Add a new class to your project and paste this code:
using System;
using System.Windows.Forms;
class MyButton : Button {
protected override void OnClick(EventArgs e) {
// Your code here
//...
base.OnClick(e);
}
}
Change the code in OnClick() to do what you want to do. Compile. You'll now have your own button control on the top of the toolbox. And can drop as many copies of it as you want on a form. They'll all behave the same without having to add any code in the form.
Probably the easiest way would be to have each button invoke the same click handler. Then inside of your handler use the Sender instead of hard coding Button1.
private void buttons_Click(object sender, EventArgs e)
{
var theButton = (Button) sender;
if (theButton.BackColor != Color.Lime)
{
theButton.BackColor = Color.Lime;
}
else
{
theButton.BackColor = Color.White;
}
}
You can get the button that raised the Click event by casting sender to Button.
You can then add the same handler to every button.
I'm a VB guy.... in VB.Net you can add multiple handlers for events and connect multiple events to the same handler.
This sub hooks all clicks to color the buttons.
Private Sub ColorButtons(sender As System.Object, e As System.EventArgs) _
Handles Button1.Click, Button2.Click, ..
I do this all the time accidentally because I drag/copy a control to make a new one and the new button gets added to the original's events.
Other Subs can handle the same events to do other work - both will execute.
No idea how to do this in C#.
The proper way to do this really is to associate each button's click event to the function you have coded for that purpose (you want the function to run when the button is clicked, right?), so add the following (or similar) to an appropriate section of your code:
MyButton1.Click += new RoutedEventHandler(buttons_Click);
MyButton2.Click += new RoutedEventHandler(buttons_Click);
etc...
You can associate as many controls to the event handler as you like.
What I usually do before is this:
private void button2_Click(object sender, EventArgs e)
{
button1.PerformClick();
}
This code will just simply run the codes under button1_Click.
But try not to practice as such and just simply put it in a function/method just like what David suggested.

Triggering a "Click" event without user input

I have a Windows Forms Link Label, "Refresh", that refreshes the display.
In another part of my code, part of a separate windows form, I have a dialog that changes the data loaded into the display in the first place. After executing this other code, pressing "Refresh" updates the data correctly.
Is there a simple way for the dialog menu to "click" the "refresh" Link Label after it has finished altering the data?
Using Visual Studio 2008.
For button is really simple, just use:
button.PerformClick()
Anyway, I'd prefer to do something like:
private void button_Click(object sender, EventArgs e)
{
DoRefresh();
}
public void DoRefresh()
{
// refreshing code
}
and call DoRefresh() instead of PerformClick()
EDIT (according to OP changes):
You can still use my second solution, that is far preferable:
private void linkLabel_Click(object sender, EventArgs e)
{
DoRefresh();
}
public void DoRefresh()
{
// refreshing code
}
And from outside the form, you can call DoRefresh() as it is marked public.
But, if you really need to programmatically generate a click, just look at Yuriy-Faktorovich's Answer
You could call the PerformClick method. But Generally it is better to have the Click event of the button call a Refresh method you write. And the menu call that method as well. Otherwise your menu depends on the button being there.
Edit:
A LinkLabel implements the IButtonControl explicitly. So you could use:
((IButtonControl)button).PerformClick();
you can use a method to refrech display, the bouton_click and the dialogBox call this method
public void refrechDate()
{
}
private void button_click(...)
{
refrechData();
}
private void MyMethod()
{
// ...
// calling refresh
this.button1_Click(this.button1, EventArgs.Empty);
// ...
}
private void button1_Click(object sender, EventArgs e)
{
// refresh code
}

Categories