How to create a top level xaml that mimic a windows in wpf - css

I want to create a window that I can style its shape (for example close button). Based on my reading I can not style these sections of a windows as they are not client sections and they are handeled by OS.
To create my own winmdows style, I created a border less windows( style=none) and I am trying to place the buttons on window by myself.
In my design the top of window should have an image on left hand side and close/minimize/maximise buttons on right.
I have this xaml which would shows logo on left and a button on right.
<DockPanel>
<DockPanel DockPanel.Dock="Top" Height="50" Background="DarkGray" Width="Auto" cal:Message.Attach="[Event MouseLeftButtonDown] = [Action MoveWindow]">
<Image DockPanel.Dock="left" Height="47" Source="/Resources/Images/Toplogo.png"/>
<Button DockPanel.Dock="Right" Width="16" Height="14" x:Name="CloseWindow" />
</DockPanel>
But when I run the application, I can see that the logo is on left, but close button is not on the right, but it is in the middle and if I change the window size, logo and button move to the middle of window ( the dockpanel is not resize.)
How can I create such behaviour in xaml?

The DockPanel defaults to `LastChildFill="True"' so the final element within the DockPanel (your button) fills the remaining space.
You can fix it by adding HorizontalAlignment="Right" to the button, or LastChildFill="False" to the inner DockPanel.

I would use a Grid and create two rows. One for the "window bar" and the other for the "content".
Example:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</<Grid.ColumnDefinitions>
<!-- Header w/ button -->
<Grid Grid.Row="0" Background="DarkGray" Height="50" Grid.Column="0" HorizontalAlignment="Stretch">
<Image Height="47" Source="/Resources/Images/Toplogo.png" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Button Width="16" Height="14" x:Name="CloseWindow" HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
<!-- Body of Window -->
<Grid Grid.Row="1" Grid.Column="0">
</Grid>
</Grid>

Related

Maui: Change gridView template conditionally

I have a grid inside a CollectionView and I need to change the layout based on a certain condition, changing dynamically the size of the columns and rows and hiding/showing some specific columns.
The datasource of the collectionView is always the same.
Basically, I want to achieve something like this:
Default layout:
Alternative layout:
I saw that maybe I could use the DataTemplateSelectors, but is that the best way or is there another method?
You can use the Grid in the Collectionview and set the Grid format.
First, you can set the CollectionView ItemsLayout. Here is the example.
<CollectionView ItemsSource="{Binding Items}"
ItemsLayout="VerticalGrid, 3">
it will divide the CollectionView list into three vertical parts.
Second, you can make a Grid to preserve the data.
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
</Grid.ColumnDefinitions>
<Image Grid.Row="0"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Row="1"
Text="{Binding Location}" />
</Grid>

Uno platform flyout menu sub item placed outside visible region on Andorid

When using MenuFlyoutSubItem the sub items pane is placed outside visible area on Android:
Android emulator showing sub items not visible :
Here is the code I am using
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Column="1" Grid.Row="0">
<SymbolIcon Symbol="More"/>
<Button.Flyout>
<MenuFlyout Placement="BottomEdgeAlignedRight">
<MenuFlyoutItem Text="Item 1"/>
<MenuFlyoutSubItem Text="Sub Items">
<ToggleMenuFlyoutItem Text="Sub Item 1"/>
<ToggleMenuFlyoutItem Text="Sub Item 2"/>
<ToggleMenuFlyoutItem Text="Sub Item 2"/>
</MenuFlyoutSubItem>
</MenuFlyout>
</Button.Flyout>
</Button>
</Grid>
This issue has been fixed in the previews of Uno Platform 3.11, where the layout of popups was incorrectly detecting the bounds of the current window.
You can try the preview bits by checking the experimental box in your nuget package managed and install the latest 3.11.0-dev.XX packages.

Flexlayout or grid for better screen sizes handling

Xamarin layout advice
Hi given the nature of mobile devices screen sizes as a rule of thumb when building screen
would you say use "Flexlayout" all the time rather than a grid.
It is my understanding that the flexlayout is more suitable for adapting to various screens sizes without building complexity in your pages.
Still do not understand "Grow and shrink" despite reading few documentations.
How would you describe grow and shrink?
Sample one
<Grid
RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="3*" />
<RowDefinition Height="6*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" BackgroundColor="Green">
<Label Text="Header with logo"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
</StackLayout>
<StackLayout Grid.Row="1" BackgroundColor="LightBlue">
<Label Text="Content"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
</StackLayout>
<StackLayout Grid.Row="2" BackgroundColor="Red">
<Label Text="Footer"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
</StackLayout>
</Grid>
VS
<FlexLayout Direction="Column">
<!-- Header -->
<Label Text="HEADER"
FontSize="Large"
BackgroundColor="Aqua"
HorizontalTextAlignment="Center" />
<!-- Body -->
<FlexLayout FlexLayout.Grow="1">
<!-- Content -->
<Label Text="Content"
FontSize="Large"
BackgroundColor="Gray"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
FlexLayout.Grow="1" />
</FlexLayout>
<!-- Footer -->
<Label Text="FOOTER"
FontSize="Large"
BackgroundColor="Pink"
HorizontalTextAlignment="Center" />
</FlexLayout>
Grow setting of 1. This means that all the extra vertical space is allocated to this blank Label like these screenshot.
I add second label called content2, if I set grow 0, content2 will not fill extra vertical space
if I set grow 1, content2 will fill extra vertical space
shrink property plays a role when the Wrap property is set to NoWrap and the aggregate width of a row of children is greater than the width of the FlexLayout, or the aggregate height of a single column of children is greater than the height of the FlexLayout. Normally the FlexLayout will display these children by constricting their sizes. The Shrink property can indicate which children are given priority in being displayed at their full sizes.
You can download this demo, and test it by yourself.
https://developer.xamarin.com/samples/xamarin-forms/UserInterface/FlexLayoutDemos/

PopUp to contains other controls like DateTime Picker,dropdownlist

newbie here. I remember in Win10, there is a PopUp UI which can contains many controls like Dropdown box, DatePciker and others. This PopUp can be constructed in Xaml.
I am developing an app for Tablet.
It is possible to use such PopUp in Xamarin forms which contains Dropdown List, DatePicker, Time Picker? It is advisable to do such complex UI ? will it cause problem in Android and iOS?
Problem : How to create PopUp in Xaml
so ,I can use a button to open or close it.
var button = new Button {Text = "Show Popup"};
button.Clicked += (s, e) => popup.Show();
Update
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.View.PopUpDemo"
Title="PopUp Demo"
Icon="itemIcon3">
<Grid>
<Grid>
<!--Your Page xaml-->
<Button x:Name="btnPopUp" Click="ShowPopUp"/>
</Grid>
<Grid HorizontalOptions="Fill" BackgroundColor="##60000000" IsVisible="{Binding GridVisibility}">
<Grid VerticalOptions="CenterAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width="9*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<Frame Grid.Column="1" Padding="0" HasShadow="True" OutlineColor="#e6e6e6">
<Grid BackgroundColor="White" RowSpacing="0" ColumnSpacing="0">
<!--content for popup-->
</Grid>
</Frame>
</Grid>
</Grid>
</Grid>
</ContentPage>
I would like to know :
I am using a normal ContentPage.
1) In it, i place your MarkUp <Grid> ,I remove <ContentPage.Content>. Is this correct?
2) Is Frame will be the PopUp ?
3) what code to use in btnPopUp to show the PopUp?
Thanks
Yes you can achieve it without any performance issue. Either you can use an overlay to show pop up as shown below
<Grid>
<Grid>
<!--Your Page xaml-->
</Grid>
<Grid HorizontalOptions="Fill" BackgroundColor="##60000000" IsVisible="{Binding GridVisibility}">
<Grid VerticalOptions="CenterAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width="9*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<Frame Grid.Column="1" Padding="0" HasShadow="True" OutlineColor="#e6e6e6">
<Grid BackgroundColor="White" RowSpacing="0" ColumnSpacing="0">
<!--content for popup-->
</Grid>
</Frame>
</Grid>
</Grid>
</Grid>
This one is quite simple. Here i have added grid to achieve this. You can also use other layouts. But for performance grid is better as per xamarin team.
For the second grid i have added Visibility property so that you can wire up with any event.
Here i have added backgroundcolor for popup ##60000000 so that when popup appears background will be transparent with light black color effect.
If you need to have same pop up in multiple screens you can use 3rd party plugin https://github.com/rotorgames/Rg.Plugins.Popup which will make you work easier. For this you have to make a new contentpage, replace the contentpage with
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
x:Class=""
BackgroundColor="##60000000"
InputTransparent="True"
HasSystemPadding="True"
CloseWhenBackgroundIsClicked="False">
<pages:PopupPage.Animation>
<animations:MoveAnimation
PositionIn="Bottom"
PositionOut="Bottom"/>
</pages:PopupPage.Animation>
<Grid>
<!--your xaml code-->
</Grid>
Note:Replace contentPage with PopupPage in youpage.xaml.cs. To get popup effect your layout should be like 1st example i shown. Here you can also get nice animation effects. More details you can see in their site.
Now you can call the pop up by calling:navigation.PushPopupAsync(new YourContentPage());
And remove the popup by calling await PopupNavigation.RemovePageAsync(this);
Hope this will be useful for you

WPF Expander Auto-Resize

I have a custom Expander that I've created as a template:
<local:MultiplyConverter x:Key="multiplyConverter" />
<ControlTemplate x:Key="AnimatedExpander" TargetType="{x:Type Expander}">
<DockPanel>
<ToggleButton x:Name="ExpanderButton" DockPanel.Dock="Top" Template="{StaticResource ExpanderButton}" Content="{TemplateBinding Header}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" OverridesDefaultStyle="True">
</ToggleButton>
<ScrollViewer x:Name="ExpanderContentScrollView" DockPanel.Dock="Bottom" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Bottom">
<ScrollViewer.Tag>
<sys:Double>0.0</sys:Double>
</ScrollViewer.Tag>
<ScrollViewer.Height>
<MultiBinding Converter="{StaticResource multiplyConverter}">
<Binding Path="ActualHeight" ElementName="ExpanderContent"/>
<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</ScrollViewer.Height>
<ContentPresenter x:Name="ExpanderContent" ContentSource="Content" />
</ScrollViewer>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ExpanderContentScrollView" Storyboard.TargetProperty="Tag" To="1" Duration="0:0:0.3">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ExpanderContentScrollView" Storyboard.TargetProperty="Tag" To="0" Duration="0:0:0.3">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
When I actually go to instantiate the Expander inside a grid, the code looks like this:
<Expander Template="{StaticResource AnimatedExpander}" ExpandDirection="Down" OverridesDefaultStyle="True" FontSize="11.0" Foreground="#CC000000" Header="Export Options" HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.Column="0" CornerRadius="0" Background="Transparent" Margin="10,0,10,0" BorderBrush="#FFAAAAAA" BorderThickness="0,0,0,0.5">
<ComboBox Grid.Column="0" ItemsSource="{Binding CurrentSlicerManager.Exporters}" DisplayMemberPath="Name" SelectedItem="{Binding CurrentSlicerManager.SelectedExporter, Mode=TwoWay}" Grid.Row="0" Margin="0,0,0,10"></ComboBox>
</Border>
<ContentControl Content="{Binding CurrentSlicerManager}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"></ContentControl>
</Grid>
</Expander>
As you can see, I've bound the content inside the Expander to a ContentControl. The ContentControl uses a DataTemplate to determine which .xaml I should load into the Expander. So, I have two DataTemplates that look like this:
<DataTemplate DataType="{x:Type MLC:MLRasterSlicerManager}">
<local:MLRasterSlicerExportSettings></local:MLRasterSlicerExportSettings>
</DataTemplate>
<DataTemplate DataType="{x:Type MLC:MLVectorSlicerManager}">
<local:MLVectorSlicerExportSettings></local:MLVectorSlicerExportSettings>
</DataTemplate>
So, I have two .xaml files (MLRasterSlicerExportSettings and MLVectorSlicerExportSettings) which get loaded... and this works fine. The issue is that the height of these two interfaces are different. When, I change the combobox which controls which file to load into the expander, I would expect the expander to automatically resize itself. And, this does happen when it first loads the expander with the smaller height and then I switch it to load the one with the larger height value... the expander does resize itself to accommodate the larger file... but if I switch it back to the smaller one, then it never resizes to the appropriate height. It just remains the same height as the largest file. Can anyone recommend how to get this expander to automatically resize to the size of the content?

Resources