Change MenuFlyoutPresenter to align with button in UWP - xaml

I am trying to get the MenuFlyout to align bottom-left of the button. I can achieve this if i put the button at the left of the screen, but if the button is anywhere else the MenuFlyout is always centered right under the button. I suspect that I have to create a template and change a property in there but I do not know what I need to change to achieve this.
I've pasted my xaml below with a note of where i suspect I need to make the change. I am new to xaml, any help or guidance will be much appreciated. Thanks!
<Page
x:Class="ButtonMenuFlyout.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ButtonMenuFlyout"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<Style x:Key="BasicTextStyle" TargetType="MenuFlyoutItem">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="13" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Padding" Value="0,0,0,0" />
<Setter Property="MinHeight" Value="36" />
</Style>
<Style x:Key="MenuFlyoutPresenterStyle1" TargetType="MenuFlyoutPresenter">
<Setter Property="Background" Value="#FFFFFF" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Padding" Value="20,0,20,16" />
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuFlyoutPresenter">
<Grid Background="{TemplateBinding Background}">
<!--[change property in here]-->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button x:Name="buttonMenuFlyout"
Content="..."
VerticalAlignment="Top"
HorizontalAlignment="right"
Padding="16,4"
Margin="120,10,0,5"
Background="White">
<Button.Flyout>
<MenuFlyout Opened="MenuFlyout_Opened" MenuFlyoutPresenterStyle="{StaticResource MenuFlyoutPresenterStyle1}">
<MenuFlyoutItem Style="{StaticResource BasicTextStyle}" Text="Settings" Click="MenuFlyoutItem_Click" />
<MenuFlyoutItem Style="{StaticResource BasicTextStyle}" Text="Feedback" Click="MenuFlyoutItem_Click_1"/>
<MenuFlyoutItem Style="{StaticResource BasicTextStyle}" Text="Notebook" Click="MenuFlyoutItem_Click_2" />
</MenuFlyout>
</Button.Flyout>
</Button>
</Grid>
</Page>

In your MenuFlyout_Opened method, you can explicitly call ShowAt(UIElement, Point) method.
This first parameter will probably be your buttonMenuFlyout; the second one, your offset which might roughly be new Point(0, buttonMenuFlyout.ActualHeight).

Related

UWP FlyOut template acting differently on different systems

I have a custom template for a flyout, and it works fine on about half of our systems, but it completely breaks on the other half.
Here's what the menu looks like when it works:
And here's what it looks like when it doesn't work... the semi-transparency is completely black, and the contents of the menu itself are completely off the screen:
You can ignore how the second screenshot is wider and how the stuff behind the menu looks different. That's just a different resolution and a different set-up, but this issue happens even when they're the same.
As noted in the picture, when the MenuFlyout appears (when I open the menu via clicking the AppBarButton), I need a semi-transparent area to appear in front of the rest of the page. This is accomplished by putting a big rectangle in the flyout's template, causing the shadow behind the flyout to be extended out over the rest of the page.
Here's the code of the button that triggers the flyout to show:
<AppBarButton
x:Name="MenuBtn"
Height="72"
Label="{StaticResource Menu}"
AllowFocusWhenDisabled="False"
Click="MenuBtn_Click"
CornerRadius="0"
Style="{StaticResource AppBarIconButtonStyle}"
TabIndex="9"
Width="72"
Margin="0,0,16,8"
Loaded="MenuBtn_Loaded"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.AlignBottomWithPanel="False">
<AppBarButton.Flyout>
<MenuFlyout x:Name="HbgMenuFlyout" MenuFlyoutPresenterStyle="{StaticResource MenuFlyoutPresenterStyle}" Opening="MenuFlyout_Opening" Closing="HbgMenuFlyout_Closing" Closed="MenuFlyout_Closed">
<MenuFlyoutItem x:Name="SelectRoomBtn" x:Uid="HbgMenu_Select_Room" Style="{StaticResource MenuFlyoutItemStyleDark}" Click="SelectRoomBtn_Click" /> <!-- mobile only -->
<MenuFlyoutItem x:Name="PhysicianProfileBtn" x:Uid="HbgMenu_Physician_Preferences" Style="{StaticResource MenuFlyoutItemStyleDark}" Click="Physician_Preferences_Click" />
<MenuFlyoutItem x:Name="SystemSettingsBtn" x:Uid="HbgMenu_Settings" Style="{StaticResource MenuFlyoutItemStyleDark}" Click="SystemSettingsBtn_Click" />
<MenuFlyoutItem x:Name="HomeBtn" x:Uid="HbgMenu_Home" Style="{StaticResource MenuFlyoutItemStyleDark}" Click="HomeBtn_Click" />
<MenuFlyoutItem x:Name="LogoutBtn" x:Uid="HbgMenu_Logout" Style="{StaticResource MenuFlyoutItemStyleDark}" Click="LogoutBtn_Click" />
</MenuFlyout>
</AppBarButton.Flyout>
</AppBarButton>
Here's the code for the style attached to the MenuFlyout:
<Style x:Key="MenuFlyoutPresenterStyle" TargetType="MenuFlyoutPresenter">
<Setter Property="RequestedTheme" Value="Dark"/>
<Setter Property="Background" Value="Gray" />
<Setter Property="BorderBrush" Value="Gray" />
<Setter Property="BorderThickness" Value="0,0,0,0" />
<Setter Property="Padding" Value="0" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.IsHorizontalRailEnabled" Value="False" />
<Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="False" />
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
<Setter Property="MinWidth" Value="{ThemeResource FlyoutThemeMinWidth}" />
<Setter Property="MaxWidth" Value="2000" />
<Setter Property="MinHeight" Value="{ThemeResource MenuFlyoutThemeMinHeight}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuFlyoutPresenter">
<controls:FlyoutGridControl />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And here's the code for that control:FlyoutGridControl:
<UserControl
x:Class="CardiologyApp.Controls.FlyoutGridControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CardiologyApp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400" >
<RelativePanel x:Name="RootGrid" HorizontalAlignment="Stretch">
<Rectangle x:Name="Shield" Width="2000" RelativePanel.AlignRightWith="MenuFlyoutPresenterScrollViewer" PointerPressed="Rectangle_PointerPressed" />
<ScrollViewer x:Name="MenuFlyoutPresenterScrollViewer"
Width="516"
RelativePanel.AlignRightWithPanel="True"
HorizontalAlignment="Right"
Background="Gray"
AutomationProperties.AccessibilityView="Raw">
<ItemsPresenter />
</ScrollViewer>
<Border x:Name="MenuFlyoutPresenterBorder"
VerticalAlignment="Stretch"
RelativePanel.Below="MenuFlyoutPresenterScrollViewer"
RelativePanel.AlignRightWithPanel="True"
Height="1000"
Background="Gray"
Width="516"
/>
</RelativePanel>
The workaround for the developers is to comment out the in the control:FlyoutGridControl.
Any suggestions on how to make the behavior consistent across systems? We're all on Windows 10 Enterprise.
MenuFlyout is not suitable for pop-up layer fixed on the right sidebar. In higher system versions, MenuFlyout is not limited by the size of the application window, which will invalidate your layout.
According to your actual display picture, SplitView should be a control that better meets your needs.
This is a simplified layout structure:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<CommandBar VerticalAlignment="Top" HorizontalAlignment="Stretch">
<AppBarButton/>
</CommandBar>
<SplitView DisplayMode="CompactOverlay" OpenPaneLength="516"
PanePlacement="Right" x:Name="AppSplitView" Grid.Row="1">
<SplitView.Pane>
<Grid>
<!--Used to display list items-->
<ListView/>
</Grid>
</SplitView.Pane>
<SplitView.Content>
<Grid>
<!--Main content display area-->
</Grid>
</SplitView.Content>
</SplitView>
</Grid>
If you want to apply the above code, you need to use ListViewItem in ListView to replace your MenuItem.
If you need to show your options, just set:
AppSplitView.IsPaneOpen = True;
For more information about SplitView and its display effect, you can check this document:
Split view

UWP Xaml GridViewItem: Remove margin

I want to create a grid of images without any margin between them. I tried to achieve this through a GridView. If there is an easier way, please let me know.
I found this answers on StackOverflow:
https://stackoverflow.com/a/10492464
https://stackoverflow.com/a/23817931/5739170
And ended up with this code:
<Page.Resources>
<Style x:Key="MyGridViewItemStyle" TargetType="GridViewItem">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewItem">
<GridViewItemPresenter ContentMargin="0" Padding="0" Margin="0" BorderThickness="0"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<GridView ItemsSource="{x:Bind FieldList}" Margin="0,50,0,0" Padding="0" BorderThickness="0" ItemContainerStyle="{StaticResource MyGridViewItemStyle}" IsItemClickEnabled="True" ItemClick="OnItemClick">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:Field">
<Image Width="20" Height="20" Margin="0" Source="{x:Bind ImagePath}"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock x:Name="text">Hallo!</TextBlock>
</StackPanel>
</Grid>
But there is still a margin left:
Screenshot
I have also tried to use negative margins but when I use them clicks aren't recognized correctly anymore.
How can I remove the margins?
Seems like the GridViewItem has a default MinWidth of 44px.
You can set it to 0 via your GridViewItemStyle:
<Setter Property="MinWidth" Value="0" />
EDIT: it also has a default MinHeight, you might want to set that to 0 as well.
The code below should work:
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="Margin" Value="0"/>
</Style>
</GridView.ItemContainerStyle>
Your code is good. If you add a Grid in the DataTemplate (with a Background), you will see there is no margin between grids :
<DataTemplate x:DataType="data:Field">
<Grid Background="Red">
<Image Width="20" Height="20" Margin="0" Source="{x:Bind ImagePath}"/>
</Grid>
</DataTemplate>
Your problem is the following : you set a fixed size for Image control wich all of them is in a container, but the container doesn't have a fixed, so images are centered in the container.
I see two solutions. First is to remove the fixed size for Image control and use Strecth property to fill correctly :
<DataTemplate x:DataType="data:Field">
<Image VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Stretch="UniformToFill"
Margin="0"
Source="{x:Bind ImagePath}"/>
</DataTemplate>
For the first solution, you must be sure of the filling behavior of the container. You can do something like :
<GridViewItemPresenter ContentMargin="0"
Padding="0"
Margin="0"
BorderThickness="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch" />
The second solution is to set a fixed size on the container directly :
<Style x:Key="MyGridViewItemStyle"
TargetType="GridViewItem">
<Setter Property="Padding"
Value="0" />
<Setter Property="Margin"
Value="0" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="Width"
Value="20" />
<Setter Property="Height"
Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewItem">
<GridViewItemPresenter ContentMargin="0"
Padding="0"
Margin="0"
BorderThickness="0"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Add Xaml hyperlink to rectangle

I am trying to add a hyperlink to a xaml rectangle and it's not working. I tried adding hyperlink with a button and it works. How can I add hyperlink to a group of rectangle for the code below.
How to give Hyperlink for below Code
<Rectangle Fill="Red" HorizontalAlignment="Left" Height="38" Margin="1038,74,0,0" Stroke="Black" VerticalAlignment="Top" Width="426"/>
<TextBlock HorizontalAlignment="Left" Margin="1173,82,0,0" TextWrapping="Wrap" Text="Pending Sites " VerticalAlignment="Top" Height="24" Width="142" Foreground="#FFF7F6F1" FontSize="20" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto">
<TextBlock.RenderTransform>
<CompositeTransform Rotation="-0.098"/>
</TextBlock.RenderTransform>
</TextBlock>
Code I tried with Button which is working fine
<Button Content="Click to go to desc page" Click="Button_Click_1" Margin="62,376,0,357"/>
private void Button_Click_1(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(dPlanner2x.MyPageDetails));
}
Rather than trying to turn a Rectangle into a click-able object, you are much better off if you apply a Style to a Button.
An example of a Style to change the look of a Button is given below:
<Style x:Key="btnCommand" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="rct"
TextBlock.Foreground="White"
Background="DarkGray"
BorderBrush="DarkGray"
BorderThickness="1"
Cursor="Hand"
UseLayoutRounding="True"
SnapsToDevicePixels="True"
Margin="10"
Height="24"
MinWidth="75">
<ContentPresenter TextBlock.FontStyle="Segoe UI Semibold"
TextBlock.FontSize="14"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="rct"
Property="TextBlock.Foreground"
Value="DarkGray" />
<Setter TargetName="rct"
Property="Background"
Value="LightGray" />
<Setter TargetName="rct"
Property="BorderBrush"
Value="DarkGray" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="rct"
Property="TextBlock.Foreground"
Value="DarkGray" />
<Setter TargetName="rct"
Property="Background"
Value="White" />
<Setter TargetName="rct"
Property="BorderBrush"
Value="LightGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Obviously, you will want something that looks completely different, but the Style template above can be easily modified to fit your needs.

how to set the color of toggle button from style already defined in app xaml?

I had created a button and i want to change its color using style from app xaml.
But,i don't get the exact code and i am new to xaml.
Can any one help me with some example.
I am also confused to use which property to change color means background or foreground?
<Window
x:Class="ToolBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ToolBar"
Width="300"
Height="300">
<DockPanel>
<ToolBarTray
DockPanel.Dock="Top"
IsLocked="True"
Orientation="Horizontal">
<ToolBar
x:Name="ToolBar1">
<ToggleButton>
<ToggleButton.Style>
<Style
TargetType="{x:Type ToggleButton}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Label>Play</Label>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Label>Pause</Label>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Panel.Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
</ToolBar>
</ToolBarTray>
</DockPanel>
</Window>
Within a toolbar, the two statements:
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Panel.Background" Value="Transparent" />
causes the toggle button to appear in the normal state when the toggle button is checked, however nothing changes when you hover over the checked toggle button.
If I wrap the toggle button in another layout, say wrap layout:
<Window
x:Class="ToolBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ToolBar"
Width="300"
Height="300">
<WrapPanel>
<ToggleButton>
<ToggleButton.Style>
<Style
TargetType="{x:Type ToggleButton}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Label>Play</Label>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Label>Pause</Label>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Panel.Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
</WrapPanel>
</Window>
the two statements:
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Panel.Background" Value="Transparent" />
You can find tutorial in the folowing url
http://social.msdn.microsoft.com/Forums/pl-PL/wpf/thread/7e565a41-0aad-40a3-a3c4-666c5caf38fe
Thanks
Deepak

How to change button background color depending on bound command canexecute?

I Have a ItemTemplate in which is a simple button bound on a command, which can be executable or not depending on some property.
I'd like the color of this button's background to change if the command isn't executable.
I tried several methods, but I can't find anyway to do this purely in XAML (I'm doing this in a study context, and code behind isn't allowed).
Here's my code for the button :
<Button x:Name="Dispo" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Center" Width="30" Height="30"
Grid.Column="2" Grid.Row="0"
Command="{Binding AddEmpruntCommandModel.Command}"
CommandParameter="{Binding ElementName='flowCars', Path='SelectedItem'}"
vm:CreateCommandBinding.Command="{Binding AddEmpruntCommandModel}" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Button.Background" Value="Green"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Button.Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
You can specify your own template like that:
<Button Content="OK" Command="{Binding SomeCommand}">
<Button.Style>
<Style>
<Setter Property="Button.Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border" Background="Green">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>