Place a popup under a button (UWP, XAML, C#) - c#

I have created a Button. When the button is pressed a Popup appears. The Problem is, the popup is on the top left side while the button is on the Right side.
What do I have to do in XAML to make the popup appear under the button?
I even tried to place the popup in the top rightcorner via HorizontalAllignment. The Problem then is that the popup is outside my program (Right next to it. Literally).

just use the new DropDownButton in the new winUi library, it has a build in popup which comes under the button and the button even has an arrow on right side, it is perfect for your scenario. just use the nuget package, docs are here : https://learn.microsoft.com/en-us/uwp/toolkits/winui/

You can use the Flyout which is attached to specific controls including Button, then You can use the Placement property to specify where a flyout appears: Top, Left, Bottom, Right, or Full. So you can use the Placement property to specify the flyout to appear under the button as the following code.
<Button Content="Click me">
<Button.Flyout>
<Flyout Placement="Bottom">
<TextBlock Text="This is a flyout!"/>
</Flyout>
</Button.Flyout>
</Button>
By the way, as we suggestion in the Remark part,
Do not use a Popup if a Flyout, MenuFlyout, ToolTip or ContentDialog (MessageDialog for a Windows 8 app) is more appropriate.

Related

WPF custom title bar with Windows 11 caption buttons

To edit non client area, I need to create my own title bar in my WPF app setting WindowStyle to none and non resizable. I have created my own caption button but it don't get the feel of Windows 11. When we hover mouse over middle button we can see a window snap option as seen in this image
Is there anyway to achieve this, I mean there should be, I even tried many nuget packages having custom Window, but I didn't got what I wanted.
All I want is to get a Window with System's default Window behavior but can have a Sliding panel from left which is even over title bar, somewhat like this but I dont want to make title bar myself I want systems default.
Even if its custom made I want it perfectly same as System's Default Window
Its already in many Windows apps :- Clock ,Mail, Even Word .
In each of this apps left panel is over title bar and even preserving the system's default window behavior, Please Please Please tell me I have been looking for it from 2 months.
Nuget Package I tried : https://github.com/Kinnara/ModernWpf
code I tried:
<Window '''''default code ''''
''''''''''''''''''''''
''''''''''''''''''''''
''''''''''''''''''''''
WindowStyle="None"
ResizeMode="NoResize">
<!--This created blank window with no title bar-->
<Grid>
<!--creating title bar-->
<Grid ''''' code so grid appear as title bar on top
and we can drag too>
<!--caption buttons-->
<button ''''button with '-' and style as
windows caption button and minizimes window
when clicked'''''''''''/>
<button ''''button with 'square symbol' and style as
windows caption button and maximize or restore window
when clicked'''''''''''/>
<button ''''button with 'close symbol' and style as
windows caption button and close window
when clicked'''''''''''/>
</Grid>
<!---
rest of the code
""""""""""""""""""
"""""""""""""""
""""""""""""""""--->
</Grid>
<Window/>

How to disable opening WPF popup

I have a Popup and a ToggleButton. I set a binding like this:
<ToggleButton x:Name="myToggle" Content="{Binding MyData.Title}" />
<Popup IsOpen="{Binding IsChecked, ElementName=myToggle}" >
<TextBlock Text="{Binding MyData.Details}" />
</Popup>
As you see, I bound the toggle button's content to MyData.Title and the popup's content to MyData.Details.
Now I had the criteria MyData.ShowDetails. If it is true the popup can open and if it is false the popup should not be opened.
How can I set a binding to achieve this?
I tested these bindings on the Popup but no one works:
Visibility="{Binding MyData.ShowDetails, Converter={StaticResource BooleanToVisibilityConverter}}"
IsEnable="{Binding MyData.ShowDetails}"
You could put a panel (Grid ) on top of all the content in your window.
That needs to have a background set but it can be low opacity if you still want to see the window content.
Make that visible only when the popup is shown and collapse otherwise.
Make sure you set focus to your popup when it's shown.
.
Bear in mind.
Popups are separate windows.
They are intended to be shown briefly and have a number of potential drawbacks if you show them for longer periods. EG other applications can appear under them and they don't move with their "parent" window/control.
You might find a modal window is easier and suits better, depending on your exact requirements.
Just instantiate a window and use
PopupWindow newWindow = new PopupWindow();
newWindow.ShowDialog();
Where PopupWindow is just any old window styled to look like you want the popup.
This will guarantee the user can't somehow interact with any other window in your app.
.
Another possibility is to show your "popup" content in a grid which appears on top of everything inside your main window.
That's how editing data works in this:
https://gallery.technet.microsoft.com/scriptcenter/WPF-Entity-Framework-MVVM-78cdc204
The plus or minus of that approach is that it's in the one window.
--- Brian Kress ---
I found a special answer in my case. Instead of disabling Popup, I should disable the ToggleButton:
<ToggleButton x:Name="myToggle" Content="{Binding MyData.Title}"
IsEnabled="{Binding MyData.ShowDetails}"/>
<Popup IsOpen="{Binding IsChecked, ElementName=myToggle}" >
<TextBlock Text="{Binding MyData.Details}" />
</Popup>
It works perfect!
Note: This is not a general answer for Popup. Welcome to anyone who has an answer.

Flyout - WPF (mahApps)

I'm trying to close a flyout when a click on his or on another side of the window, I use the ExternalCloseButton=Left property. Is this okay? I also tried removing the property AutoCloseEnabled, but could not get results.
When I use a flyout with the property EnabledAutoClose, when closed, the focus is lost in the control it was.
You can help solve this problem?
<mahApps:MetroWindow.Flyouts>
<mahApps:FlyoutsControl>
<mahApps:Flyout Position="Bottom"
AutoCloseInterval="3000"
IsOpen="{Binding IsOpen}"
IsAutoCloseEnabled="True"
ExternalCloseButton="Left">
</mahApps:Flyout>
</mahApps:FlyoutsControl>
</mahApps:MetroWindow.Flyouts>
If you set IsPinned="False" then the Flyout will be closed on left mouse click outside the Flyout.
<Controls:Flyout Height="75"
CloseButtonVisibility="Collapsed"
IsPinned="False"
Position="Bottom"
TitleVisibility="Collapsed">
<TextBlock VerticalAlignment="Center" Text="This is an AppBar" />
</Controls:Flyout>
Sample is from the main demo. Hope this helps.
You can use PreviewMouseLeftButtonUp of the MainWindow or whatever view contains the flyout and set the isOpen to false. If you want to close it only when user clicks the outside of the flyout than you can check it with isMouseOver property of the flyout.

Flyout's "Light Dismissal" Causing 2 Taps to be Required to Open Next Flyout

I have two buttons that show Flyouts when clicked. I am displaying them the same way as demonstrated in the XAML UI Basics sample:
private void ButtonTapped(object sender, TappedRoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element != null)
{
FlyoutBase.ShowAttachedFlyout(element);
}
}
My problem is that if Button 1's flyout is open, the next tap on the screen closes the flyout. This is fine, but if the next tap happens to be on Button 2, I want the button's tap event to be fired and open its flyout. Instead, the button doesn't register a tap at all and closes Button 1's flyout.
This results in needing to tap two times - one to dismiss the Button 1's flyout, and a second to show Button 2's flyout.
In other words:
Current Flow:
Tap Button 1
Button 1's Flyout is opened
Tap Button 2
Button 1's flyout is closed, (Button 2, nor Page registers the tap)
Tap Button 2
Now Button 2's flyout is opened
What I'm Looking For:
Tap Button 1
Button 1's Flyout is opened
Tap Button 2
Button 1's flyout is closed, Button 2's flyout opens.
How can I do this? I've tried intercepting the Tapped event for the page, but when the flyout is open, it seems to intercept the Tapped event so it can be used for the Flyout's light dismissal
Would overriding the style of the Flyout, or the FlyoutPresenterStyle help me here? Or perhaps opening the Flyout in a more MVVM-ish way which would allow me for finer control on how the Flyout is opened/closed?
I'm not sure how to get around this!
Here is something I found on Microsoft documents:
When dismissing with a tap, this gesture is typically absorbed and not passed on to the UI underneath. For example, if there’s a button visible behind an open flyout, the user’s first tap dismisses the flyout but does not activate this button. Pressing the button requires a second tap.
You can change this behaviour by designating the button as an input pass-through element for the flyout. The flyout will close as a result of the light dismiss actions described above and will also pass the tap event to its designated OverlayInputPassThroughElement. Consider adopting this behaviour to speed up user interactions on functionally similar items. If your app has a favourites collection and each item in the collection includes an attached flyout, it's reasonable to expect that users may want to interact with multiple flyouts in rapid succession.
[!NOTE] Be careful not to designate an overlay input pass-through element which results in a destructive action. Users have become habituated to discreet light dismiss actions which do not activate primary UI. Close, Delete or similarly destructive buttons should not activate on light dismiss to avoid the unexpected and disruptive behaviour.
In the following example, all three buttons inside FavoritesBar will be activated on the first tap.
<Page>
<Page.Resources>
<Flyout x:Name="TravelFlyout" x:Key="TravelFlyout"
OverlayInputPassThroughElement="{x:Bind FavoritesBar}">
<StackPanel>
<HyperlinkButton Content="Washington Trails Association"/>
<HyperlinkButton Content="Washington Cascades - Go Northwest! A Travel Guide"/>
</StackPanel>
</Flyout>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="FavoritesBar" Orientation="Horizontal">
<HyperlinkButton x:Name="PageLinkBtn">Bing</HyperlinkButton>
<Button x:Name="Folder1" Content="Travel" Flyout="{StaticResource TravelFlyout}"/>
<Button x:Name="Folder2" Content="Entertainment" Click="Folder2_Click"/>
</StackPanel>
<ScrollViewer Grid.Row="1">
<WebView x:Name="WebContent"/>
</ScrollViewer>
</Grid>
private void Folder2_Click(object sender, RoutedEventArgs e){
Flyout flyout = new Flyout();
flyout.OverlayInputPassThroughElement = FavoritesBar;
flyout.ShowAt(sender as FrameworkElement);}

Attach a single close button on the tabcontrol in C#

How i can attach a single close button on the tabcontrol in C#.
There is a many way to attach a close button individually on each tabpages but I want to attach only single(e.g.) we can see on microsoft visual stdio 2008.
So Plz help me.
Here is a cheap way to do it, which might get you started:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<TabControl DockPanel.Dock="Top">
<TabItem Header="Test1" />
<TabItem Header="Test2" />
<TabItem Header="Test3" />
<TabItem Focusable="False">
<TabItem.Header>
<Button Command="{Binding CloseTab}" Content="X" Width="21" HorizontalAlignment="Stretch" />
</TabItem.Header>
</TabItem>
</TabControl>
</DockPanel>
</Window>
You then are left to implement a public ICommand CloseTab field or property on your DataContext, and style the tab control to your liking.
Edit:
If you use this method:
Wiring up the button is tricky. You have to be careful not to close the tab that contains the button
This isn't well adapted to dynamically created tabs, because you have to ensure the close button is appended to the list
You have to figure out how to re-select the last selected tab, when you close the selected tab
You'll also have weird behavior when tabs start to wrap
The tab-stop behavior is hard to get right. You can't make the last TabItem focusable, since focus is used to determine what to close, but tabbing to the close button breaks the normal TabItem keyboard flow
I have come up with a style that makes the button look like a regular tab, with a bold X on it, which makes it visually more like IE8, and fixes the keyboard selection problem. But it is complicated, and this solution is complicated enough.
Ultimately, a close button on every tab jives better with the tab control's default behavior. The only problem with that solution is that it takes up more space. You could cheat and make the close button collapse until you mouse over the tab item, though that's sort of a user-experience no-no, unless you just shrink it.
If you are serious about following through with the separate close button, I suggest you look at this article, and adapt what they do for the scroll buttons to your close button:
http://www.blogs.intuidev.com/post/2010/02/10/TabControlStyling_PartThree.aspx
Ignore what they do for close buttons :)
Would it be possible to have your tabcontrol on another container control and let that control's close button do the job?

Categories

Resources