Xamarin Forms - Change Cursor to Wait Cursor - c#

In most desktop apps, if you're waiting for something, the mouse cursor will change to a wait cursor. Obviously, phones are a bit different. But, in UWP land, we'd like the mouse cursor to change to a wait cursor while async operations are occurring.
Is there a way to do this in standard Xamarin Forms? Or, with a 3rd party library?
The hope would be that on phones, there would be some other visual indicator that something is occurring. I.e. keyboard colour changes or something similar.
If not, I'm guessing I'll have to implement some dependency injected code for each platform. Any tips?

Not an answer to your UWP question, but this is how you can handle things on phone:
You could add a Grid over the whole page and make it grey and half transparent so the rest of your page gets "greyed out". Then add an ActivityIndicator to the middle of the Grid to indicate something is loading. Set IsVisible of the Grid to a bool value that indicates that something is loading/happening.
This is what I got on one of my pages:
<Grid BackgroundColor="##60000000"
IsVisible="{Binding IsLoading}">
<Grid VerticalOptions="CenterAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*" />
<ColumnDefinition Width="9*" />
<ColumnDefinition Width=".5*" />
</Grid.ColumnDefinitions>
<Frame Grid.Column="1"
HorizontalOptions="Center"
VerticalOptions="Center"
Padding="0"
HasShadow="True"
OutlineColor="#e6e6e6">
<Grid BackgroundColor="White"
RowSpacing="0"
ColumnSpacing="0">
<StackLayout>
<ActivityIndicator IsRunning="true"
Margin="10"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Label Text="{i18n:Translate Text=loading_contacts}"
Margin="20,0,20,10"
HorizontalOptions="Center"
VerticalOptions="Center"/>
</StackLayout>
</Grid>
</Frame>
</Grid>
</Grid>

Mine is a similar answer to Dennis, with a bit more re-use.
I created a control template in App.xaml
<ControlTemplate x:Key="ActivityIndicatorTemplate">
<Grid>
<ContentPresenter />
<StackLayout Style="{StaticResource BlockingPanel}"
IsVisible="{TemplateBinding BindingContext.IsBusy}">
<ActivityIndicator Style="{StaticResource ActivityIndicatorStyle}"
IsVisible="{TemplateBinding BindingContext.IsBusy}"
IsRunning="{TemplateBinding BindingContext.IsBusy}" />
</StackLayout>
</Grid>
</ControlTemplate>
Here are the styles
<Style x:Key="BlockingPanel" TargetType="StackLayout">
<Setter Property="BackgroundColor" Value="{StaticResource BlockingColor}" />
<Setter Property="HorizontalOptions" Value="FillAndExpand" />
<Setter Property="VerticalOptions" Value="FillAndExpand" />
</Style>
<Style x:Key="ActivityIndicatorStyle" TargetType="ActivityIndicator">
<Setter Property="Color" Value="White" />
<Setter Property="HorizontalOptions" Value="CenterAndExpand" />
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
</Style>
<Color x:Key="BlockingColor">
<x:Arguments>
<x:Double>0</x:Double>
<x:Double>0</x:Double>
<x:Double>0</x:Double>
<x:Double>0.75</x:Double>
</x:Arguments>
</Color>
Then you can use it on any page like this
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Incident.Pages.LoginPage"
ControlTemplate="{StaticResource ActivityIndicatorTemplate}"
Title="Login">
...
</ContentPage>

Related

Set navigation side menu background image in Xamarin Forms

In Xamarin forms I want to use an image ( png file ) I created as background for a side "hamburger" menu. For example, here is some menu:
Two questions:
1) What's the best image size to use for the menu background
2) How do I put a ListView that contains my menu options on top of the background image ?
I tried using the grid but wasn't successful at stacking them. Code below is a quick summary of how the MasterDetailPage is structured.
//Menu
<MasterDetailPage.Master>
<ContentPage>
<ContentPpage.Content>
<AbsoluteLayout> //Also tried FlexLayout and RelativeLayout
<Image Source="blah" Aspect="Fill"/>
<Grid>
<ListView/>
</Grid>
</AbsoluteLayout>
</ContentPpage.Content>
<ContentPage>
</MasterDetailPage.Master>
//Page content
<MasterDetailPage.Detail>
<ContentPage>
///Page content
</ContentPage>
</MasterDetailPage.Detail>
The goal is to get the side menu looking something like this:
I just tried one sample solution. This is my master page :
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="using:MasterDetailPageNavigation"
x:Class="MasterDetailPageNavigation.MasterPage"
Padding="0,40,0,0"
Icon="hamburger.png"
Title="Personal Organiser">
<Grid>
<Image Source="Default-Portrait.png" Aspect="AspectFill" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
<StackLayout Margin="0,20,0,0">
<ListView x:Name="listView" x:FieldModifier="public" BackgroundColor="Transparent">
<ListView.ItemsSource>
<x:Array Type="{x:Type local:MasterPageItem}">
<local:MasterPageItem Title="Contacts" IconSource="contacts.png" TargetType="{x:Type local:ContactsPage}" />
<local:MasterPageItem Title="TodoList" IconSource="todo.png" TargetType="{x:Type local:TodoListPage}" />
<local:MasterPageItem Title="Reminders" IconSource="reminders.png" TargetType="{x:Type local:ReminderPage}" />
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding IconSource}" />
<Label Grid.Column="1" Text="{Binding Title}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</Grid>
</ContentPage>
There is a trick to have Grid as a parent. If you put 2 controls in same Cell it will overlap. Here my background image "Default-Portrait" will get overlapped by my StackLayout (listview) which has Background Color set as "Transparent".
For the Size of the Image, I would use multiple Size and put those images in the appropriate drawable-hdpi directory in android and iOS assets.
Let me know if you need any more clarifications.
This is a result:

XAML Changing font size dynamically iOS Xamarin app

I want to make a label appear the same size proportionally regardless of the resolution of the target device
I have the following code
<StackLayout
Orientation="Vertical" Margin="0,0,0,0" Padding="0,0,0,0"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Label Text="{Binding AccountName}"
Style="{StaticResource labelStylePrimaryBold}"
HorizontalOptions="StartAndExpand" />
</StackLayout>
I have the above code and this in my App.xaml
<Style x:Key="labelStylePrimaryBold" TargetType="Label">
<Setter Property="TextColor" Value="#414042" />
<Setter Property="FontAttributes" Value="Bold" />
<Setter Property="FontSize" Value="15" />
</Style>
I need to make this available across my app, I've seen the following code on
https://developer.xamarin.com/guides/xamarin-forms/user-interface/text/fonts/
label.FontSize = Device.OnPlatform (
24,
Device.GetNamedSize (NamedSize.Medium, label),
Device.GetNamedSize (NamedSize.Large, label)
);
But my label does not have an ID, how would I go about linking this up?
I'm very new to Xamarin, but this seems like a fairly obvious thing to want to do.
You can use Xamarin forms NamedSize Enumeration
You can choose from:
Default
Large
Medium
Micro
Small
Example:
<Label FontSize="small" Text="Joe"></Label>
<Label FontSize="Large" Text="Joe"></Label>

Adding different elements based on button clicked

I have two different panels like this
.
When i click on the first button, it should display some text, second button should display a datagrid and so on.
How do i change the elements of the right hand panel to achieve this. Initially i just used different windows. Is there a way to call them into the panel ? Then I though of hiding elements based on the button clicked, but that would look like a mess. Should i code the elements when a button is clicked otherwise ? How is this functionality usually added ? What concepts do i need to learn to implement this ?
After coming across this question and seeing the absolutely poor answers that you had been provided with, I felt obliged to offer you a decent answer. There are many different ways of achieving your requirements. Here is probably, the simplest method:
Declare one Grid in MainWindow that displays your three Buttons on the left hand side and the three possible controls on the right hand side:
<Grid>
<Grid.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Width" Value="150" />
<Setter Property="Height" Value="40" />
<Setter Property="Content" Value="Button" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<ToggleButton Grid.Row="0" Name="Button1" Style="{StaticResource ButtonStyle}" />
<ToggleButton Grid.Row="1" Name="Button2" Style="{StaticResource ButtonStyle}" />
<ToggleButton Grid.Row="2" Name="Button3" Style="{StaticResource ButtonStyle}" />
<TextBlock Grid.Column="1" Grid.Row="0" Name="TextBlock" Text="Here is some text"
HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding
IsChecked, ElementName=Button1, Converter={StaticResource
BooleanToVisibilityConverter}}" />
<Rectangle Grid.Column="1" Grid.Row="1" Name="Rectangle" Width="150" Height="40"
Fill="LightGreen" Stroke="Black" Visibility="{Binding IsChecked, ElementName=
Button2, Converter={StaticResource BooleanToVisibilityConverter}}" />
<RadioButton Grid.Column="1" Grid.Row="2" Name="RadioButton" Content="Here is an
option" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{
Binding IsChecked, ElementName=Button3, Converter={StaticResource
BooleanToVisibilityConverter}}" />
</Grid>
Note that I used ToggleButtons here simply because they have a bool IsChecked property that is set when they are clicked on and can be used to show and hide the controls on the right hand side. To do this, we use a BooleanToVisibilityConverter (which was introduced into the .NET Framework in .NET 4.5) to convert our bool ToggleButton.IsChecked property values into Visibility values.
Now this example probably wasn't exactly what you were thinking of, but I'm sure that it will give you enough of an example for you to experiment with and come up with your desired UI... remember that you are going to have to do some work too.
Create your Xaml page with all the views Textboxt, DataGrid and TextBox2. then you just need to play with the Visibility of controls

Actually using the Tile Control in MahApps Metro?

I have been working with MahApps Metro UI for couple days now and i have realy enjoyed it. WHen looking through their documentation, i wanted to use the tile control and make something along the lines of this:
Their documentation, located on this page: http://mahapps.com/controls/tile.html , only tells me this:
The following XAML will initialize a Tile control with its Title set to "Hello!" and its Count set to 1.
<controls:Tile Title="Hello!"
TiltFactor="2"
Width="100" Height="100"
Count="1">
</controls:Tile>
When i entered this into my simple application, i get one small rectangle. How am i actually supposed to use the control to mimic the Windows 8 start screen with tiles?
I'm currently building a large application using the MahApps Metro library and it's amazing! In terms of getting an app to look like the Windows 8 start screen, heres quick example I whipped up.
XAML
<Window x:Class="Win8StartScreen.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
Title="MainWindow" Height="513" Width="1138" WindowState="Maximized" WindowStyle="None" Background="#191970">
<Window.Resources>
<Style x:Key="LargeTileStyle" TargetType="mah:Tile">
<Setter Property="Width" Value="300" />
<Setter Property="Height" Value="125" />
<Setter Property="TitleFontSize" Value="10" />
</Style>
<Style x:Key="SmallTileStyle" TargetType="mah:Tile">
<Setter Property="Width" Value="147" />
<Setter Property="Height" Value="125" />
<Setter Property="TitleFontSize" Value="10" />
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="87*"/>
<ColumnDefinition Width="430*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="83*"/>
<RowDefinition Height="259*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
Text="Start"
FontWeight="Light"
Foreground="White"
FontSize="30"
FontFamily="Segoe UI" />
<WrapPanel Grid.Row="1" Grid.Column="1" Width="940" Height="382" HorizontalAlignment="Left" VerticalAlignment="Top">
<mah:Tile Title="Mail" Style="{StaticResource LargeTileStyle}" Content="ImageHere" Background="Teal" Margin="3"/>
<mah:Tile Title="Desktop" Style="{StaticResource LargeTileStyle}" Margin="3">
<mah:Tile.Background>
<ImageBrush ImageSource="Images/windesktop.jpg" />
</mah:Tile.Background>
</mah:Tile>
<mah:Tile Title="Finance" Style="{StaticResource LargeTileStyle}" Background="Green" />
<mah:Tile Title="People" Style="{StaticResource LargeTileStyle}" Background="#D2691E" />
<mah:Tile Title="Weather" Style="{StaticResource LargeTileStyle}" Background="#1E90FF" />
<mah:Tile Title="Weather" Style="{StaticResource SmallTileStyle}" Background="#1E90FF" />
<mah:Tile Title="Store" Style="{StaticResource SmallTileStyle}" Background="Green" />
</WrapPanel>
</Grid>
</Window>
There are lots of ways to do this to make it cleaner and more reusable using styles and templates, but this was just a quick way to show the use of the Tiles control.

Windows 8 - XAML - Putting Grid Inside ListView

Inside my XAML/C# app for Windows 8 Store, I am trying to create a ListView where each ListItem is a horizontal Grid, so I am using the XAML below:
<ListView Name="ResultsView">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="4*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding BestRank}" Grid.Column="0"/>
<TextBlock Text="{Binding PlayerName}" Grid.Column="1"/>
<TextBlock Text="{Binding BestScore}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When I run this program, the listview contains all the items from the list it is bound to (through code behind). However in every list-item, contents of all three columns appear together without any space between them. When I create a similar grid outside the listview, it displays fine and takes up entire width of the screen and divides it between the three columns as specified in the XAML above.
What am I doing wrong?
I believe the issue is the ItemContainerStyle needs to have a HorizontalContentAlignment of Stretch. Try this adding this to the ListView:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
Both the ListBox and the Grid should have HorizontalContentAlignment="Stretch"
Specify the width of the grid or add the style as a resource to the grid. Add this right after your </Grid.ColumnDefinitions> line.
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Right" />
<Setter Property="Margin" Value="4" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Grid.Resources>
This will set the properties to all of the TextBlocks in the Grid. You might only need the Margin property. Also consider the properties Width and Padding. You can override this default by setting the property on any given TextBlock to something that isn't the default from the Style.
The default ItemsPanelTemplate is a stack panel as far as I recall meaning that it won't automatically give it's children stretch behavior. You will need to change it, I will edit in a sec just on my mobile waiting for my laptop to boot up :)
Edit:
Er no ignore that I was thinking of ItemsControl, JBrooks is right, just make sure HorizontalContentAlignment is set to Stretch as the default is Left.
<ListView Name="ResultsView" HorizontalContentAlignment="Stretch">
That should work fine - any controls that use XXXXContentAlignment seem to default to Left which I think its a bit inconsistent vs other controls (such as Grid)
actually this is not a problem of Listview. Problem is where you are putting it in? Put your list view in grid. It should work
<ListView Name="ResultsView"
HorizontalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Background="Yellow">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="4*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding BestRank}" Grid.Column="0"/>
<TextBlock Text="{Binding PlayerName}" Grid.Column="1"/>
<TextBlock Text="{Binding BestScore}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Categories