Windows Phone 8.1 MenufFyout acting up(bug?) - xaml

I'm trying to have a MenuFlyout on every item of a ListView. This work's so far without a problem in the way i want it to. But there's one thing that never get solved no matter how much i try. No matter what property i set, the MenuFlyout always clamps to the right side of the screen. i've checked every link with documentation and questions in regards of Windows Phone 8.1 applications using this but without luck. Here's some of the code.
<StackPanel>
<AppBarButton Icon="More"
ClickMode="Release"
Foreground="Black"
IsDoubleTapEnabled="False"
IsHoldingEnabled="False"
RenderTransformOrigin="0.5,0.5"
VerticalAlignment="Top"
HorizontalAlignment="Right">
<AppBarButton.Flyout>
<MenuFlyout>
<MenuFlyout.MenuFlyoutPresenterStyle>
<Style TargetType="MenuFlyoutPresenter">
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="Margin" Value="25,0,25,25"></Setter>
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
</Style>
</MenuFlyout.MenuFlyoutPresenterStyle>
<ToggleMenuFlyoutItem Text="Copy" HorizontalAlignment="Left" />
<ToggleMenuFlyoutItem Text="Delete" HorizontalAlignment="Left" />
</MenuFlyout>
</AppBarButton.Flyout>
<AppBarButton.RenderTransform>
<CompositeTransform Rotation="90" TranslateX="0" TranslateY="0"/>
</AppBarButton.RenderTransform>
</AppBarButton>
</StackPanel>

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

Custom control with text box and text block

I would like to build a validation text box, which would be a normal UWP TextBox wrapped within a StackPanel, which also contains a TextBlock. The intent is that a validation message can be shown beneath the text box when there is a validation error.
I know I can do this by creating a custom control, but this would require me to implement all the properties I need and create a bunch of dependency properties, etc.
I'm hoping there is an easier way, where I can just completely derive the text box, but override the display template for it and include a label beneath it.
You can get most of the way there in XAML using the built-in IDataErrorInfo-based validation machinery and defining a control template for the TextBox's Validation.ErrorTemplate. There's a pretty good article at this link:
The XAML from the article at the link above follows, also check out this discussion on WPF's built-in validation here.
<Style TargetType="{x:Type Label}">
<Setter Property="Margin" Value="5,0,5,0" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0,2,40,2" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="true">
<Border Background="OrangeRed" DockPanel.Dock="right" Margin="5,0,0,0"
Width="20" Height="20" CornerRadius="5"
ToolTip="{Binding ElementName=customAdorner,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
<TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center"
FontWeight="Bold" Foreground="white" />
</Border>
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
<Border BorderBrush="red" BorderThickness="1" />
</AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Datatrigger with DynamicResource works only on last item in ItemsControl

My DashBoardSimpleCountObject has 2 values: MyName and MyValue.
I use an ObservableCollection<DashboardSimpleCountObject> called MyData.
I want to show a picture, as long as MyValue is null.
However, the picture ("loading") is only shown at the last item of my ObservableCollection (no matter, how many items are in there). As soon as a MyValue is set (with anything other than null), it is automatically updated and shown correctly - that works fine at all items.
<ItemsControl x:Name="_control" ItemsSource="{Binding MyData}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="25">
<Label FontSize="14" Content="{Binding MyName}" />
<Label Margin="0,25" HorizontalContentAlignment="Right" FontSize="29" FontWeight="ExtraBold" Foreground="{Binding MyColor}">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Content" Value="{Binding MyValue}" />
<Style.Triggers>
<DataTrigger Binding="{Binding MyValue}" Value="{x:Null}">
<Setter Property="Content">
<Setter.Value>
<Image Width="32" Height="32" Source="{DynamicResource loading}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
What am I doing wrong?
Thank you very much in advance! :)
It seems, the nature of DynamicResource causes this issue.
Simply changing DynamicResource to StaticResource did the trick.
So, the DataTrigger worked just fine from the beginning. The image simply did only show up once due to being loaded as a DynamicResource.

How Can I Reuse an Icon in Resources in UWP? In WPF, I'd use x:Shared=false

I am trying to create a button Style that I can use for a "Lookup" button throughout my UWP app. However, the icon only appears on the first button on the screen. I tried this solution using templates, but it is not working for me. Thanks for the help.
Code:
<Page.Resources>
<ControlTemplate x:Key="FindSymbolTemplate">
<SymbolIcon Symbol="Find" Foreground="White" />
</ControlTemplate>
<Style TargetType="Button" x:Key="LookupButton">
<Setter Property="Content">
<Setter.Value>
<ContentControl Template="{StaticResource FindSymbolTemplate}" />
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
....
<Button x:Name="tourNumLookup"
Style="{StaticResource LookupButton}"
Grid.Column="1"
Margin="10,0"
VerticalAlignment="Center" />
....
<Button x:Name="customerIdLookup"
Style="{StaticResource LookupButton}"
VerticalAlignment="Center"
Grid.Column="1"
Grid.Row="1"
Margin="10,0" />
The two buttons in the UI. Only the first has the SymbolIcon content.
#Romasz's solution absolutely works, but what if you want a lightly different Foreground on the SymbolIcon inside another Button?
Here's a potentially more flexible way that I normally go with.
First let's create a base Style that holds some default values for all the icons.
<Style x:Key="Style-Icon-Base"
TargetType="ContentControl">
<!-- If you don't specify the Foreground, it will use its ancestor's -->
<!--<Setter Property="Foreground"
Value="White" />-->
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Width"
Value="20" />
<Setter Property="Height"
Value="20" />
<Setter Property="Padding"
Value="0" />
</Style>
Then we create a new icon Style which inherits from the one above. Note within the ControlTemplate I have used TemplateBinding to make property values dynamic. TemplateBinding isn't available inside a DataTemplate.
<Style x:Key="Style-Icon-Find"
BasedOn="{StaticResource Style-Icon-Base}"
TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<!--
'cause you cannot change the size of the SymbolIcon, we insert a Viewbox here,
otherwise you don't need it.
-->
<Viewbox Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<SymbolIcon Symbol="Find"
Foreground="{TemplateBinding Foreground}" />
</Viewbox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This way you have created a highly reusable icon Style, to use it, have a look at the following Buttons:
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Margin="4"
Padding="8"
BorderBrush="LightBlue">
<ContentControl Width="36"
Height="36"
Foreground="DarkCyan"
Style="{StaticResource Style-Icon-Find}" />
</Button>
<!-- Note how I defined the Foreground at the Button level and it flows down to the icon -->
<Button Foreground="DarkGoldenrod"
Margin="4">
<StackPanel Orientation="Horizontal">
<ContentControl Style="{StaticResource Style-Icon-Find}"
Width="16"
Height="16" />
<TextBlock Text="Search"
VerticalAlignment="Center"
Margin="8,0,0,0" />
</StackPanel>
</Button>
<Button Margin="4"
Padding="4">
<ContentControl Style="{StaticResource Style-Icon-Find}" />
</Button>
</StackPanel>
And they look like:
Generally UI elements can be used once (or saying different - have only one parent) - this is probably why it only works for the first button in your case. One solution may be to define DataTemplate and use it as ContentTemplate, so each button creates its own icon:
<Page.Resources>
<DataTemplate x:Key="FindTemplate">
<SymbolIcon Symbol="Find" Foreground="White" />
</DataTemplate>
</Page.Resources>
...
<Button x:Name="tourNumLookup" ContentTemplate="{StaticResource FindTemplate}"
Grid.Column="1" Margin="10,0" VerticalAlignment="Center" />
<Button x:Name="customerIdLookup" ContentTemplate="{StaticResource FindTemplate}"
VerticalAlignment="Center" Grid.Column="1" Grid.Row="1" Margin="10,0" />
You don't need to create ControlTemplate to reuse the icon. You can simply put this SymbolIcon to the resource dictionary and use as StaticResource for the buttons' Content.
<Page.Resources>
<SymbolIcon x:Key="FindSymbol" Symbol="Find" Foreground="White" />
</Page.Resources>
<Button x:Name="tourNumLookup"
Content="{StaticResource FindSymbol}"
Grid.Column="1"
Margin="10,0"
VerticalAlignment="Center" />
<Button x:Name="customerIdLookup"
Content="{StaticResource FindSymbol}"
VerticalAlignment="Center"
Grid.Column="1"
Grid.Row="1"
Margin="10,0" />
UPDATE
BTW this is possibly a bug in the UWP platform, because I tried the following code and only the first Button rendered the icon at desing time and none of the at runtime.
<Page.Resources>
<SymbolIcon x:Key="FindSymbol" Symbol="Find" Foreground="White" />
<Style TargetType="Button" x:Key="LookupButton">
<Setter Property="Content" Value="{StaticResource FindSymbol}"/>
</Style>
</Page.Resources>
<StackPanel>
<Button x:Name="tourNumLookup"
Style="{StaticResource LookupButton}"
Margin="10,0"
VerticalAlignment="Center" />
<Button x:Name="customerIdLookup"
Style="{StaticResource LookupButton}"
VerticalAlignment="Center"
Margin="10,0" />
</StackPanel>
I tried to assign the Setter's Value directly but I got the same result. And also tried with FontIcon.

Flyout,Menu Flyout ,Combo Box occupy full screen in windows phone 8.1

I am developing an app in which combo box flyouts and menu flyouts are used ,But when I am using it , it occupy full screen in windows phone 8.1 ,Is this a default behavior or it can be controlled?
<Button.Flyout>
<Flyout Opened="Flyout_Opened">
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="Background" Value="#004469"></Setter>
</Style>
</Flyout.FlyoutPresenterStyle>
<StackPanel>
<TextBlock Foreground="White" Text="Create Text" FontSize="25" Margin="0,0,0,10" />
<TextBox x:Name="setText" Width="300" TextWrapping="Wrap"/>
<Button x:Name="addText" Background="#c0c0c0" Foreground="#004469" Content="Add" FontSize="20" Margin="0,10,0,10" Click="addText_Click"/>
</StackPanel>
</Flyout>
</Button.Flyout>
For example this occupy full screen.I need to control their width , How do I do that?
You can use this
XAML:
<MenuFlyout Placement="Top">
</MenuFlyout>
C#:
myMenuFlyout.Placement = FlyoutPlacementMode.Top;