UWP position flyout at mouse cursor - c#

I have a grid with a load of textblocks inside and a flyout with various options attached to the grid.
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem x:Name="EditButton" Text="Edit" Click="EditButton_Click"/>
<MenuFlyoutItem x:Name="DeleteButton" Text="Delete"/>
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
The problem is that the flyout will appear in the same fixed spot somewhere in the middle of the grid or I can set it programmatically to appear at an element. I want it to appear wherever the mouse was right clicked. Is this possible or am I going about this the wrong way?

I don't know how are you showing the Flyout, but in my app, I use the RightTapped event of my ListView and following code in the RightTapped event handler to achieve the same thing as you want.
private void MyListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
var tappedItem = (UIElement)e.OriginalSource;
var attachedFlyout = (MenuFlyout)FlyoutBase.GetAttachedFlyout(MyListView);
attachedFlyout.ShowAt(tappedItem, e.GetPosition(tappedItem));
}

Related

Showing a flyoutmenu on a gridview item while Narrator is active

I want to show a simple flyout menu on a gridviewitem. According to this article here: https://blogs.msdn.microsoft.com/winuiautomation/2016/01/01/ten-questions-on-programmatic-accessibility/, (paragraph 6) you should be able to just set up a handler for the doubletapped event. I also tested it in the windows phone ui.
The problem is that ,in my app, the doubletap handler never gets called when doing the 2-finger double-tap gesture while narrator is activated.
I tried to do this in my gridview:
<GridView x:Name="ImgGrid"
ItemsSource="{x:Bind AllFiles, Mode=OneWay}"
IsItemClickEnabled="True"
SelectionMode="None"
Background="{ThemeResource PaneBackgroundBrush}" Padding="8"
ItemClick="ImgGrid_ItemClick"
ItemContainerStyle="{StaticResource GridViewItemContainerStyle}"
IsDoubleTapEnabled="True"
DoubleTapped="ImgGrid_DoubleTapped">
As you can see, the doubletapped flag is enabled and there's a handler attached for the doubletapped event. But it doesn't get called with the 2-finger double tapped gesture. However, on non-mobile devices, the handler gets called by rightclicking on a gridview item.
I also tried to put the eventhandler on the gridviewitem itself:
<DataTemplate x:DataType="data:KNFBFileInfo">
<Grid x:Name="ThumbnailContainer"
Margin="8"
Width="80"
Background="Transparent"
MinHeight="100"
Height="Auto"
Holding="ThumbnailContainer_Holding"
RightTapped="ThumbnailContainer_RightTapped">
Same result as the first thing i tried...
It's really a shame that it's so hard for a developer to make
his app accessible
I just created a sample app with MenyFlyout inside DataTemplate
<DataTemplate x:Name="LastItems">
<Grid RightTapped="Grid_RightTapped">
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Item1"/>
<MenuFlyoutItem Text="Item2"/>
<MenuFlyoutItem Text="Item3"/>
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
<TextBlock Text="{Binding ''}" Padding="10" Margin="10,0" />
</Grid>
</DataTemplate>
And then Grid_RightTapped method is as follows.
private void Grid_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element != null) FlyoutBase.ShowAttachedFlyout(element);
}
Doing this, When I Right Click on Non-Mobile Devices and LongPress on Items on Mobile Devices, Flyout Shows up with no issues.
There is an official document about the "Narrator". When we Double-tap with one finger, or Hold with one finger and tap with a second, it will activate primary action. It means we tap the item once without the "Narrator". So the DoubleTapped event will never be fired.
When we Double-tap with two fingers, it will show the context menu of the select control. We should be able to add the RightTapped to the GridView. When we Double-tap with two fingers, the RightTapped will be fired.
It seems we can not select the GridViewItem in the "Narrator" mode. If we add the SelectionChanged event to the GridView, when we double tap the GridViewItem, the SelectionChanged will never be fired.

WPF Button Command for right mouse button?

I am learning about MVVM and Commands in WPF. I have a couple of buttons and I want to trigger similar commands depending on the fact if the buttons are clicked with the left or right mouse button.
Until now I used Event Handlers and I was able to determine which mouse button was pressed by checking the MouseButtonEventArgs.
<Button Content="Command Test" PreviewMouseDown="Button_PreviewMouseDown"/>
Current code behind:
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
if (e.LeftButton == MouseButtonState.Pressed) {
Debug.Print("Left");
}
else {
Debug.Print("Right");
}
}
But I don’t see anything similar if I use Commands.
How can I set different commands for a button? One command when the left mouse button is clicked and another command when the right mouse button is clicked?
<Button Content="Command Test" Command="{Binding PressLetterCommand, Mode=OneWay}"/>
Currently the Command only fires when the left mouse button is clicked. If the command would also be fired if the right mouse button is clicked and I can find out which button was clicked that would be also a solution.
I searched and I found this question and answer which uses Decorator. How do I bind a command to e.g. the right mouse button in a ControlTemplate in WPF? I tried it but as far as I understand this won’t work for my buttons.
Any suggestions?
Try this
<Button Content="Command Test">
<Button.InputBindings>
<MouseBinding Gesture="RightClick" Command="{Binding PressLetterCommand}" />
</Button.InputBindings>
</Button>

Why button changes color when I click or hover on it? Xaml windows 8

I have created a button using XAML and have defined some simple properties for it.
<Button Name="btnNext" Grid.Row="1" Content="PARA" Width="200" Grid.Column="1" Background="#FF2D2D2D" HorizontalAlignment="Right" FontSize="40" Height="380" BorderThickness="0" />
It happens that when I click on the button or put the mouse over, it changes color.
I have tried to escape this behaviour in the btnNext_Click method but it does not affect anything.
private void btnNext_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
if (button != null)
{
button.Background = new SolidColorBrush(hexToColorConvertor("#FF2D2D2D"));
START_POINT += (uint)NUMBER_OF_BUTTONS1;
ReadFile(START_POINT);
}
}
Does anyone have any idea how to resolve this?
In XAML, button have default style for different states like Normal, MouseOver, Pressed etc..
Whenever button moves from one state to another, it changes its look using default style obviously. You can find more information related to default style here
Now, If you want to override this default behavior, you can do it easily with Expression-blend. More of this can be found here and here
Hope this information will help you.. :)

How to receive focus when clicking on the background of a stackpanel?

I have a UserControl which contains a Label and a TextBox. Both are placed inside a stackpanel which is placed in a border.
I now want to receive an Event when the mouse clicks somewere inside the stackpanel or the border. I tried several things, as using transparent Backgrounds, different Events like ismousedirectlyover etc.
Is there a way i can solve this?
You can try by capturing the mousedown event inside your textbox, your label and your stackpanel and bind them all directly to the same method, you will allways get the mousedown event independent on where you clicked.
You can also try to set the
Panel.Zindex
property to a higher number in the stackpanel and then only capture the mousedown event on it.
1) Add an handler for the MouseLeftButtonDown to the border:
<Border MouseLeftButtonDown="Border_MouseLeftButtonDown">
<StackPanel Background="Transparent">
<TextBox x:Name="Text" />
</StackPanel>
</Border>
2) Set the focus manually to the TextBox:
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Text.Focus();
}
make sure to set the background of the stackpanel to transparent.

WPF - Capture an event from a control that is not on top

I have a WPF application that I am working on where there is a button that is obscured by a partially opaque rectangle overlay. The button is still visible, but it can not receive any events because they are all caught by the rectangle which is on top of it.
Is there any way to set a pass-through so that the event is received by the next visual item underneath? If not is there some other workaround that could be used in this situation?
Set IsHitTestVisible="false" on the opaque overlay.
You need to set IsHitTestVisible="False" for the control over your button.
This example shows that a button is covered by a border, but the border doesn't get any event since because of the IsHitTestVisible="False" condition of border:
<Grid Background="Yellow">
<Button Click="Button_Click" Width="100" Height="25"/>
<Border Background="Cyan" Opacity="0.4" Width="200" Height="200" IsHitTestVisible="False" />
</Grid>
C# code,
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("iiiiiii");
}
You could add the your own event to the rectangle event (or in the click event of the rectangle it self) and check there if it's with in buttons area
Rectangle.Click += your_click_event;
private void your_click_event(object sender, RoutedEventArgs e)
{
//check if it's coordinates are within the underlining button.
//fire button click event
}
But it would be more convient to set
IsHitTestVisible="False"
Like mentioned in other posts. UIElement.IsHitTestVisible Property
I would recommend to look in to routed events in WPF. Routed events get routed based primarily on the visual tree. Routed events support a RoutingStrategy of Bubble, Tunnel, or Direct.
Understanding Routed Events and Commands In WPF

Categories

Resources