I have a Button declared in XAML with a Button.Flyout nested element. I'm catching the button click and then wish to show the flyout. But I get an error:
ShowAttached was called on an element without an attached FlyoutBase.
Here's the XAML:
<Button ... Click="onMoreClicked">
<Image Source="..." />
<Button.Flyout >
...
</Button.Flyout>
</Button>
And, here's my handler:
public void onMoreClicked (object sender, RoutedEventArgs e)
{
Log.L("LP OnMoreClicked");
Button element = sender as Button;
FlyoutBase flyout = element.Flyout as FlyoutBase;
FlyoutBase.ShowAttachedFlyout(element);
}
When stepping in the debugger, element and flyout are defined, i.e. not null. Yet, ShowAttachedFlyout fails.
EDIT
For clarity, using the answer from #AryaDing-MSFT, here is my working solution:
<Button ... Click="onMoreClicked">
<Image Source="..." />
<FlyoutBase.AttachedFlyout>
...
</FlyoutBase.AttachedFlyout>
</Button>
Handler:
public void onMoreClicked (object sender, RoutedEventArgs e)
{
Button button = sender as Button;
... do stuff ...
FlyoutBase.ShowAttachedFlyout(button);
}
This issue is caused by not using FlyoutBase.AttachedFlyout to attach property, FlyoutBase.ShowAttachedFlyout and FlyoutBase.AttachedFlyout need to be used together.
Derive from official document, if the control doesn't have a flyout property, you can use the FlyoutBase.AttachedFlyout attached property instead. When you do this, you also need to call the FlyoutBase.ShowAttachedFlyout method to show the flyout.
So you can refer to the code like following.
XAML:
<Button Click="onMoreClicked">
<FlyoutBase.AttachedFlyout>
<Flyout>
<TextBlock Text="This is a flyout!"/>
</Flyout>
</FlyoutBase.AttachedFlyout>
</Button>
Code behind:
private void onMoreClicked(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
FlyoutBase.ShowAttachedFlyout(element);
}
Because the button has a flyout attribute, you can also write directly like following.
<Button>
<Button.Flyout >
<Flyout>
<TextBlock Text="This is a flyout!"/>
</Flyout>
</Button.Flyout>
</Button>
Related
I'm using Avalonia.Controls.DataGrid. By default, when the grid has focus and Enter is pressed, it automatically handles the event and moves the selection to the next item. How can I prevent this default behavior? I'd like to have a custom Enter KeyDown handler instead.
So the KeyDown event cannot be used here, because specifically for Enter it's swallowed by the DataGrid before custom code can handle it.
Instead, Key bindings work. You can bind the key to a command like this:
<DataGrid ...>
<DataGrid.KeyBindings>
<KeyBinding Gesture="Enter" Command="{Binding SelectCommand}" />
</DataGrid.KeyBindings>
...
</DataGrid>
This also stops the grid from moving to next item when Enter is pressed.
Try this :
1- Give your datagrid a name (use x:name)
2- put this in your constructor :
yourDataGridName.KeyDown += yourDataGridName_KeyDown;
3- add this handler :
protected void yourDataGridName_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
//Put your custom code here
}
}
https://github.com/AvaloniaUI/Avalonia/issues/10130
I use AddHandler for DataGrid. As the developer advised.
dataGrid.AddHandler(KeyDownEvent, dataGrid_PreviewKeyDown, RoutingStrategies.Tunnel);
private void dataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
//
e.Handled = true;
}
}
Button on click method is not calling
Button code :
<asp:Button ID="personalSub" runat="server" ValidationGroup="personal" Text="Save" CausesValidation="false" OnClick="InsertPersonalDetail" />
C# Code :
protected void InsertPersonalDetail(object sender, EventArgs e)
{
Console.WriteLine("hello");
MessageBox.Show("hello");
}
If you have any problem on the page then you must see a compiler error.
You do NOT have compiler error witch is means that asp.net finds the InsertPersonalDetail function on code behind.
From what I see you call inside the button click two functions that are for desktop programming (not for web page).
Neither one can have any visible effect on your click - there is no console there to see anything, neither user interface to open the MessageBox.
protected void InsertPersonalDetail(object sender, EventArgs e)
{
Console.WriteLine("hello"); // have no effect on web page
MessageBox.Show("hello"); // have no effect on web page
}
So its called but you don't see it by just wait a pop up to appears
To check this out, run it with debuger and add a break point there.
Or add a literal on page and add some text there to verify that is called.
eg, add on page
<asp:Literal runat="server" ID="txtLiteral" />
and on code behind
protected void InsertPersonalDetail(object sender, EventArgs e)
{
txtLiteral.Text += "InsertPersonalDetail called <br />";
}
To get the selected item of a ListView it's easily by:
myObject myObjectName = e.Item as myObject ;
And that's ItemTappedEventArgs has Item attribute.
But how to get the if I want to position a button inside the cells and I want to get the item of the cell whose button is clicked while EventArgs has no Item attribute?
try something like this, bind your item list to Itemsource of the listview, if you have a button or image which has a tapped event mapped like below, you can get the selected item from the list. the code is casting to Image as the event is mapped to Tap gesture of an Image.
Image inside listview will be,
<Image Source="app_dots" Grid.Column="2" VerticalOptions="Start">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="more_Tapped"
NumberOfTapsRequired="1"/>
</Image.GestureRecognizers>
</Image>
and the code for Tap event,
async void more_Tapped(object sender, System.EventArgs e)
{
ApplicationModel applicationModel = ((ApplicationModel)((Image)sender).BindingContext);
if (applicationModel != null)
{
//do your logic;
}
}
The simplest way to do that task is putting CommandParameter="{Binding .}" into your ListView and in the code behind:
TappedEventArgs tappedEventArgs = e as TappedEventArgs;
myObject myObjectName = tappedEventArgs.Parameter as myObject ;
I have a small problem. I am developing an online seat reservation system which allow users to click and select seats. I am using buttons for seats. I am writing a method for the button click event for all buttons. I need to know how to identify the id of the button, user clicked. thanks in advance.
When you use a button clicked event, the signature of the method that'll handle the event goes like this:
protected void foo (object sender, EventArgs e)
sender in this case is the button that was clicked. Just cast it to Button again and there you have it. Like this:
Button button = (Button)sender;
string buttonId = button.ID;
You can have all your buttons pointing their Click event to the same method like this.
The first parameter of your event handler (object source or sometimes object sender) is a reference to the button that was clicked. All you need to do is cast it and then you can retrieve the id value, e.g.:
void Button_Click(object sender, EventArgs e)
{
Button button = sender as Button;
if (button != null)
{
//get the id here
}
}
I think there's another way to do this method you may not thought of it,
why don't you put an
Image control
you only need switch the image's color for this method, the first one we assume that it's Red and it means free seat, and the second one is Blue and means taken .
here is a link you may need to know about this issue How to change color of Image at runtime
Hope I could gave you a better idea. thank you
I know this is an old thread but hopefully it helps someone out there having the same trouble I was here in 2019! This is my solution using the Tag property of the button with Binding through XAML. Worked great for me, even though it might be a little hacky:
In your button click event:
private void Button_Click(object sender, RoutedEventArgs e)
{
Button EditButton = (Button)e.Source;
int id = Convert.ToInt32(EditButton.Tag);
//do your stuff
}
In your XAML:
<Button Click="Button_Click" Content="Edit" Tag="{Binding whateverInt}" />
I have an ASP.NET control that has an onclick event handler rendered inline on the element. I would like to call that function and have it raise the target control's server side event handler.
<asp:CheckBox ID="Foo"
runat="server"
AutoPostBack="true"
Text="Foo" />
<a href="#"
onclick="javascript:setTimeout('__doPostBack(\'Foo\',\'\')', 0)">Test
</a>
I created the checkbox, looked at the rendered function on the field, and then copied that into the onclick on the anchor element.
The anchor will raise a postback, but the event handler for the check box is not raised.
protected override void OnLoad(EventArgs e)
{
// fires for checkbox
// fires for anchor (the anchor does cause a postback)
}
void Foo_CheckedChanged(object sender, EventArgs e)
{
// fires for checkbox
// does not fire for anchor
}
protected override void OnInit(EventArgs e)
{
this.Foo.CheckedChanged += new EventHandler(Foo_CheckedChanged);
}
Is it possible to do this?
Don't try to manually determine what the javascript should look like for a postback. Use the proper API for the task... in this case, this is exactly what GetPostBackEventReference is for.
myControl.Attributes.Add("onclick", "javascript:" + ClientScript.GetPostBackEventReference(targetControl));
Why not convert the tag to an asp:linkbutton and then have the one handler for both
protected override void OnInit(EventArgs e)
{
this.Foo.CheckedChanged += new EventHandler(Foo_CheckedChanged);
this.Bar.Click+= new EventHandler(Foo_CheckedChanged);
}
The client ID of you checkbox might now be "Foo".
Use the following to make sure you use the correct ClientID for your element
<a href="#"
onclick="javascript:setTimeout('__doPostBack(\'<%= Foo.ClientID %> \',\'\')', 0)">Test
</a>