I am trying to align the last 2 buttons next to each other (side-by-side), this was a lot easier in XAML, how can I achieve this using code approach?
MainPage = new ContentPage
{
Content = new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Spacing = 40,
Children = {
new Label {
XAlign = TextAlignment.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Text = "Hey there here is where you spent your time!"
},
new Label()
{
XAlign = TextAlignment.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Text = "Time spent near beacon A: "
},
new Label()
{
XAlign = TextAlignment.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Text = "Time spent near beacon B: "
},
new Button()
{
VerticalOptions = LayoutOptions.Start,
HorizontalOptions = LayoutOptions.Start,
Text = "Start Tracking"
},
new Button()
{
VerticalOptions = LayoutOptions.Start,
HorizontalOptions = LayoutOptions.Start,
Text = "Stop Tracking"
}
}
}
};
Thanks for any input.
I got it to work with some StackLayout inception like this:
MainPage = new ContentPage
{
Content = new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Spacing = 40,
Children = {
new Label {
XAlign = TextAlignment.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Text = "Hey there here is where you spent your time!"
},
new Label()
{
XAlign = TextAlignment.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Text = "Time spent near beacon A: "
},
new Label()
{
XAlign = TextAlignment.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Text = "Time spent near beacon B: "
},
new StackLayout()
{
HorizontalOptions = LayoutOptions.Center,
Orientation = StackOrientation.Horizontal,
Children = {
new Button()
{
VerticalOptions = LayoutOptions.Start,
HorizontalOptions = LayoutOptions.Start,
Text = "Start Tracking"
},
new Button()
{
VerticalOptions = LayoutOptions.Start,
HorizontalOptions = LayoutOptions.Start,
Text = "Stop Tracking"
}
}
}
}
}
};
Related
I want to remove the spacing between the group headers in the ListView.
I want to get rid of that space to make my UI more compact.
I tried everything, from setting Spacing=0, RowSpacing=0, ItemSpacing=0 etc. Really don't know what to do now.
This is the list view GroupHeader template and some other settings for the ListView
private void SetListViewDataAsync()
{
string PageTerm = GradesPage.PageTermGlobal;
List<Data> ItemSourceData = Globals.Dataset.FindAll(item => item.TermCode == PageTerm);
listView.ItemsSource = ItemSourceData;
listView.AllowGroupExpandCollapse = true;
listView.Loaded += ListView_Loaded;
listView.PropertyChanged += ListView_PropertyChanged;
listView.GroupExpanding += ListView_GroupExpanding;
listView.GroupCollapsing += ListView_GroupCollapsing;
listView.ItemSpacing = 0;
listView.ItemSize = 200;
listView.GroupHeaderSize = 80;
SetItemTemplate();
listView.DataSource.GroupDescriptors.Add(new GroupDescriptor()
{
PropertyName = "CourseName",
KeySelector = (object obj1) =>
{
var item = (obj1 as Data);
return item;
}
});
listView.GroupHeaderTemplate = new DataTemplate(() =>
{
/*
* Remove mail text, change name to a mailto:
* Remove vertical whitespacing.
*
*/
var MainGrid = new Grid() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.FillAndExpand, HeightRequest = 50 };
MainGrid.BackgroundColor = Xamarin.Forms.Color.FromRgba(0, 0, 0, 0.60);
MainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
MainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
MainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
Binding binding1 = new Binding("Key");
binding1.Converter = new GroupHeaderConverter();
binding1.ConverterParameter = 0;
var label = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Start, FontSize = 17, FontAttributes = FontAttributes.Bold, TextColor = Color.White, Margin = new Thickness(5, 0, 0, 0) };
label.SetBinding(Label.TextProperty, binding1);
Binding binding4 = new Binding("Key");
binding4.Converter = new GroupHeaderConverter();
binding4.ConverterParameter = 3;
var classType = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center, FontSize = 10, TextColor = Color.White };
classType.SetBinding(Label.TextProperty, binding4);
var stackLayout = new StackLayout();
stackLayout.Orientation = StackOrientation.Horizontal;
stackLayout.Children.Add(label);
stackLayout.Children.Add(classType);
Binding binding2 = new Binding("Key");
binding2.Converter = new GroupHeaderConverter();
binding2.ConverterParameter = 1;
Frame border = new Frame() { Padding = 0, WidthRequest = 75, HeightRequest = 50, Margin = 10, VerticalOptions = LayoutOptions.CenterAndExpand, HorizontalOptions = LayoutOptions.End };
StackLayout score = new StackLayout() { VerticalOptions = LayoutOptions.CenterAndExpand, HorizontalOptions = LayoutOptions.Center };
Label scoreLabel = new Label() { TextColor = Color.White, FontAttributes = FontAttributes.Bold, VerticalOptions = LayoutOptions.Center, VerticalTextAlignment = TextAlignment.Center };
scoreLabel.SetBinding(Label.TextProperty, binding2);
score.Children.Add(scoreLabel);
Binding binding3 = new Binding("Key");
binding3.Converter = new GroupHeaderConverter();
binding3.ConverterParameter = 2;
border.SetBinding(BackgroundColorProperty, binding3);
border.Content = score;
MainGrid.Children.Add(stackLayout);
Grid.SetColumn(stackLayout, 0);
Grid.SetColumnSpan(stackLayout, 2);
MainGrid.Children.Add(border);
Grid.SetColumn(border, 2);
return MainGrid;
});
}
This is the ListViews ItemTemplate
private void SetItemTemplate()
{
listView.ItemTemplate = new DataTemplate(() => {
SfEffectsView effectsView = new SfEffectsView();
effectsView.TouchDownEffects = SfEffects.Ripple;
effectsView.CornerRadius = new Thickness(25, 0);
var grid = new StackLayout() { VerticalOptions = LayoutOptions.Start };
grid.BackgroundColor = Xamarin.Forms.Color.FromRgba(0, 0, 0, 0.35);
SfListView embeddedView = new SfListView() { VerticalOptions = LayoutOptions.Start };
embeddedView.AutoFitMode = AutoFitMode.Height;
embeddedView.LayoutManager = new GridLayout();
embeddedView.SelectionMode = Syncfusion.ListView.XForms.SelectionMode.None;
embeddedView.LayoutManager.SetBinding(GridLayout.SpanCountProperty, new Binding("NoOfCat"));
embeddedView.SetBinding(SfListView.ItemsSourceProperty, new Binding("CatInfoSet"));
embeddedView.ItemTemplate = new DataTemplate(() => {
var MainGrid = new StackLayout() { VerticalOptions = LayoutOptions.Start };
SfCircularProgressBar circularProgressBar = new SfCircularProgressBar() { VerticalOptions = LayoutOptions.End, HorizontalOptions = LayoutOptions.Center };
circularProgressBar.SetBinding(ProgressBarBase.ProgressProperty, new Binding("Percent"));
circularProgressBar.AnimationDuration = 0;
circularProgressBar.IndicatorOuterRadius = 0.7;
circularProgressBar.IndicatorInnerRadius = 0.6;
Binding bind = new Binding("Percent");
bind.Converter = new ColorGradientConverter();
circularProgressBar.SetBinding(ProgressBarBase.ProgressColorProperty, bind);
Grid content = new Grid();
content.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
Label score = new Label() { FontAttributes = FontAttributes.Bold, TextColor = Color.White };
score.BindingContext = circularProgressBar;
Binding scoreBinding = new Binding();
scoreBinding.Path = "Progress";
scoreBinding.StringFormat = "{0}%";
score.SetBinding(Label.TextProperty, scoreBinding);
score.HorizontalTextAlignment = TextAlignment.Center;
score.VerticalOptions = LayoutOptions.Center;
score.TextColor = Color.White;
score.FontSize = 14;
content.Children.Add(score);
circularProgressBar.Content = content;
Label label = new Label() { HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Start, FontAttributes = FontAttributes.Bold, FontSize = 14, TextColor = Color.White };
label.SetBinding(Label.TextProperty, new Binding("Description"));
MainGrid.Children.Add(circularProgressBar);
MainGrid.Children.Add(label);
return MainGrid;
});
grid.Children.Add(embeddedView);
Label l = new Label() { FontAttributes = FontAttributes.Bold, VerticalOptions = LayoutOptions.End, FontSize = 13, TextColor = Color.White, Margin = new Thickness(5, 0, 0, 0) };
l.SetBinding(Label.TextProperty, new Binding("TeachersName"));
grid.Children.Add(l);
Label l2 = new Label() { FontAttributes = FontAttributes.Italic, VerticalOptions = LayoutOptions.Center, FontSize = 12, TextColor = Color.White, Margin = new Thickness(5, 0, 0, 5) };
Binding periodB = new Binding("Period");
periodB.StringFormat = "Period {0}";
l2.SetBinding(Label.TextProperty, periodB);
grid.Children.Add(l2);
effectsView.Content = grid;
return effectsView;
});
}
Just a feeling:
In your SetListViewDataAsync() method you set:
listView.GroupHeaderSize = 80;
but on the other hand, when you set the value for listView.GroupHeaderTemplate you declare:
var MainGrid = new Grid()
{
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.FillAndExpand,
HeightRequest = 50
};
Which means you are telling the ListView that the GroupHeaderSize should be set a value of 80, and next you are telling the GroupeHeaderTemplate that it should be sized to 50, and the view to be vertically centered.
Not sure, but it might be that that extra space you are seeing is just those 80-50=30 units being set as 15 units on top and 15 at the button of your Group header.
If that is the case, there is a number of ways to solve the issue, one of them being simply changing GroupHeaderSize from 80 to 50, that is, changing your code like:
listView.GroupHeaderSize = 50;
Hope this helps!
I have the following code from SyncFusion that binds property book BookName to a Label.
listView = new SfListView() { ItemSpacing = 5 };
listView.WidthRequest = 350;
listView.ItemTemplate = new DataTemplate(() =>
{
ViewCell viewCell = new ViewCell();
var grid = new Grid() { RowSpacing = 1 };
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = 50 });
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = 200 });
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = 50 });
var contactImage = new Image()
{
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center,
HeightRequest = 50
};
contactImage.SetBinding(Image.SourceProperty, new Binding("ContactImage"));
var contactName = new Label()
{
HorizontalTextAlignment = TextAlignment.Center,
LineBreakMode = LineBreakMode.NoWrap,
FontSize = Font.SystemFontOfSize(NamedSize.Medium).FontSize,
};
contactName.SetBinding(Label.TextProperty, new Binding("ContactName"));
var contactType = new Image()
{
VerticalOptions = LayoutOptions.End,
HorizontalOptions = LayoutOptions.End,
HeightRequest = 50,
};
contactType.SetBinding(Image.SourceProperty, new Binding("ContactType"));
grid.Children.Add(contactImage, 0, 0);
grid.Children.Add(contactName, 1, 0);
grid.Children.Add(contactType, 2, 0);
viewCell.View = grid;
return viewCell;
});
However, for my project I want to be able to format two of my properties into separate font attributes.
The solution I thought of that could give me the most power is to format two string properties using formatted string and setting the label's formattedText as shown below. However, I cannot retrieve the binding in a string. Another solution I can think of is to have separate labels for each binding and combining them using a Stack Layout but that solution is inconsistent throughout my UI. Thank you in advance!
var unformattedBookName = new Binding("BookName");
var unformattedBookDescription = new Binding("BookDescription");
var formattedString = new FormattedString();
formattedString.Spans.Add(new Span { Text = "{Binding unformattedBookName}", ForegroundColor = Color.Red, FontAttributes = FontAttributes.Bold });
formattedString.Spans.Add(new Span { Text = "italic small.", FontAttributes = FontAttributes.Italic, FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)) });
var bookName = new Label()
{
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Start,
HeightRequest = 100,
FontAttributes = FontAttributes.Bold,
FontSize = 16,
FormattedText = formattedString
}
EDIT: FINAL SOLUTION
As #Jason suggested, I was able to combine both bindings into one and setting my formatted string to a single label. =)
var formattedString = new FormattedString();
var bookSpan = new Span
{
ForegroundColor = Color.Red,
FontAttributes = FontAttributes.Bold
};
bookSpan.SetBinding(Span.TextProperty, "BookName");
var bookDescriptionSpan = new Span
{
ForegroundColor = Color.Red,
FontAttributes = FontAttributes.Italic,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label))
};
bookDescriptionSpan.SetBinding(Span.TextProperty, "BookDescription");
formattedString.Spans.Add(bookSpan);
formattedString.Spans.Add(bookDescriptionSpan);
var combineBookLabel = new Label()
{
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Start,
HeightRequest = 100,
FontAttributes = FontAttributes.Bold,
FontSize = 16,
FormattedText = formattedString
};
that is not how you set a binding in code. The {Binding ...} syntax is for XAML. To do it in code use
var span = new Span() { ... };
span.SetBinding(Span.TextProperty, "BookName");
The solution suggested by Jason is right one. You can use the same to achieve your requirement.
Regards,
Dinesh Babu Yadav
[Syncfusion Team]
Question
I have a FlexLayout with following properties. Whenever any element is added to it(except the first one), extra space gets added automatically. How do I get rid of that extra space?
var flexLayout = new FlexLayout
{
Wrap = FlexWrap.Wrap,
JustifyContent = FlexJustify.Start,
AlignItems = FlexAlignItems.Center,
AlignContent = FlexAlignContent.Start,
BackgroundColor = Color.LightYellow,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.Start
};
Here is the result -
Detailed Question
My scenario is to add multiple Flexlayouts inside a StackLayout which is child of a ScrollView.
Everything is working fine except Flexlayouts takes lot of unused white space, I want them to fit to children.
So far I have tried
1. Lot of permutation combinations of FlexLayout properties.
2. Putting Flexlayout inside StackLayout/ Grid with VerticalOptionsset to Start
XAML
<Grid>
<ScrollView HorizontalScrollBarVisibility="Never">
<StackLayout x:Name="RootPanel" BackgroundColor="Cyan" Padding="5"/>
</ScrollView>
</Grid>
C# Code behind
private void Draw()
{
string[] data = new string[] { "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1" };
for (int i = 0; i < 5; i++)
{
var tempLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.Start
};
var fButton = new Button { Text = "B", HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start, WidthRequest = 50, HeightRequest = 50 };
tempLayout.Children.Add(fButton);
var equals = new Label { Text = "=>", VerticalTextAlignment = TextAlignment.Center, HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.Start, WidthRequest = 50, HeightRequest = 50, BackgroundColor = Color.LemonChiffon };
tempLayout.Children.Add(equals);
var flexLayout = new FlexLayout
{
Wrap = FlexWrap.Wrap,
JustifyContent = FlexJustify.Start,
AlignItems = FlexAlignItems.Center,
AlignContent = FlexAlignContent.Start,
BackgroundColor = Color.LightYellow,
HorizontalOptions = LayoutOptions.FillAndExpand
};
foreach (var term in data)
{
var button = new Button { Text = term, HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start, HeightRequest = 36 };
flexLayout.Children.Add(button);
var label = new Label { Text = "and", VerticalTextAlignment = TextAlignment.Center, HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.Start, HeightRequest = 50, BackgroundColor = Color.LemonChiffon };
flexLayout.Children.Add(label);
}
//var grid = new Grid { HorizontalOptions = LayoutOptions.StartAndExpand, VerticalOptions = LayoutOptions.Start, BackgroundColor = Color.Red };
//grid.Children.Add(flexLayout);
tempLayout.Children.Add(flexLayout);
//Grid.SetColumn(tempLayout, 1);
//grid.Children.Add(tempLayout);
RootPanel.Children.Add(tempLayout);
}
}
Above code gives following result, screenshot is from a UWP app but the result is same for Android also -
I am expecting something like this, there is no empty space after array of buttons.
Cause: The parent layout of FlexLayout is a StackLayout .And StackLayout will fit the size of its child elements.
Solution:
Use Grid instead of Stacklayout
private void Draw()
{
string[] data = new string[] { "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1" };
for (int i = 0; i < 5; i++)
{
var grid = new Grid
{
BackgroundColor = Color.Green
};
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(50) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(50) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
var fButton = new Button { Text = "B", HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start, WidthRequest = 50, HeightRequest = 50 };
grid.Children.Add(fButton, 0, 0);
var equals = new Label { Text = "=>", VerticalTextAlignment = TextAlignment.Center, HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.Start, WidthRequest = 50, HeightRequest = 50, BackgroundColor = Color.LemonChiffon };
grid.Children.Add(equals, 1, 0);
var flexLayout = new FlexLayout
{
Wrap = FlexWrap.Wrap,
JustifyContent = FlexJustify.SpaceAround,
AlignItems = FlexAlignItems.Start,
AlignContent = FlexAlignContent.Start,
BackgroundColor = Color.Red,
HorizontalOptions = LayoutOptions.FillAndExpand,
};
foreach (var term in data)
{
var button = new Button { Text = term, HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start, HeightRequest = 36 };
flexLayout.Children.Add(button);
var label = new Label { Text = "and", VerticalTextAlignment = TextAlignment.Center, HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.Start, HeightRequest = 50, BackgroundColor = Color.LemonChiffon };
flexLayout.Children.Add(label);
}
grid.Children.Add(flexLayout, 2, 0);
RootPanel.Children.Add(grid);
}
}
Don't use GRID inside FlexLyout it will give a huge WHITE SPACE, Use StackLayout instead
Mark the StackLayout Spacing value to 0. There is a default spacing of 10 points. https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.stacklayout.spacing?view=xamarin-forms
I am working on cross platform xamarin application and I want to create hyperlink label for "Forgot password?" on login page.
I have used following code to create label but I don't know how to create onclick event on it.
MainPage = new ContentPage
{
BackgroundImage = "background.png",
Content = new StackLayout
{
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Spacing = 50,
Children = {
new Label {
HorizontalTextAlignment = TextAlignment.Center,
Text = "Welcome, Please Sign in!",
FontSize=50,
TextColor=Color.Gray,
},
new Entry
{
Placeholder="Username",
VerticalOptions = LayoutOptions.Center,
Keyboard = Keyboard.Text,
HorizontalOptions = LayoutOptions.Center,
WidthRequest = 350,
HeightRequest = 50,
FontSize=20,
TextColor=Color.Gray,
PlaceholderColor=Color.Gray,
},
new Entry
{
Placeholder="Password",
VerticalOptions = LayoutOptions.Center,
Keyboard = Keyboard.Text,
HorizontalOptions = LayoutOptions.Center,
WidthRequest = 350,
HeightRequest = 50,
FontSize=25,
TextColor=Color.Gray,
IsPassword=true,
PlaceholderColor =Color.Gray,
},
new Button
{
Text="Login",
FontSize=Device.GetNamedSize(NamedSize.Large,typeof(Button)),
HorizontalOptions=LayoutOptions.Center,
VerticalOptions=LayoutOptions.Fill,
WidthRequest=350,
TextColor=Color.Silver,
BackgroundColor=Color.Red,
BorderColor=Color.Red,
},
new Label //for this label I want to create click event to open new page
{
Text="Forgot Password?",
FontSize=20,
TextColor=Color.Blue,
HorizontalOptions=LayoutOptions.Center,
},
}
}
};
For people who prefer to use XAML and who like to bind Command directly to the ViewModel, you can use this:
<Label HorizontalOptions="Center"
TextColor="Blue"
FontSize="20"
Text="Forgot Password?">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ForgotPasswordCommand}" />
</Label.GestureRecognizers>
</Label>
And then in your ViewModel, you'll just assign the command to your function:
public ICommand ForgotPasswordCommand => new Command(OnForgotPassword);
And then define the function with all the work get done:
private async void OnForgotPassword()
{ ... }
PS: You will need to declare that you are using System.Windows.Input;
Try this :
var forgetPasswordLabel = new Label // Your Forget Password Label
{
Text = "Forgot Password?",
FontSize = 20,
TextColor = Color.Blue,
HorizontalOptions = LayoutOptions.Center,
};
// Your label tap event
var forgetPassword_tap = new TapGestureRecognizer();
forgetPassword_tap.Tapped += (s,e) =>
{
//
// Do your work here.
//
};
forgetPasswordLabel.GestureRecognizers.Add(forgetPassword_tap);
Sample :
var forgetPasswordLabel = new Label // Your Forget Password Label
{
Text = "Forgot Password?",
FontSize = 20,
TextColor = Color.Blue,
HorizontalOptions = LayoutOptions.Center,
};
MainPage = new ContentPage
{
BackgroundImage = "background.png",
Content = new StackLayout
{
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Spacing = 50,
Children = {
new Label {
//HorizontalTextAlignment = TextAlignment.Center,
Text = "Welcome, Please Sign in!",
FontSize=50,
TextColor=Color.Gray,
},
new Entry
{
Placeholder="Username",
VerticalOptions = LayoutOptions.Center,
Keyboard = Keyboard.Text,
HorizontalOptions = LayoutOptions.Center,
WidthRequest = 350,
HeightRequest = 50,
FontSize=20,
TextColor=Color.Gray,
PlaceholderColor=Color.Gray,
},
new Entry
{
Placeholder="Password",
VerticalOptions = LayoutOptions.Center,
Keyboard = Keyboard.Text,
HorizontalOptions = LayoutOptions.Center,
WidthRequest = 350,
HeightRequest = 50,
FontSize=25,
TextColor=Color.Gray,
IsPassword=true,
PlaceholderColor =Color.Gray,
},
new Button
{
Text="Login",
FontSize=Device.GetNamedSize(NamedSize.Large,typeof(Button)),
HorizontalOptions=LayoutOptions.Center,
VerticalOptions=LayoutOptions.Fill,
WidthRequest=350,
TextColor=Color.Silver,
BackgroundColor=Color.Red,
BorderColor=Color.Red,
},
forgetPasswordLabel
}
}
};
var forgetPassword_tap = new TapGestureRecognizer();
forgetPassword_tap.Tapped += (s,e) =>
{
//
// Do your work here.
//
};
forgetPasswordLabel.GestureRecognizers.Add(forgetPassword_tap);
If the're several places with clickable Label, it makes sense to create a control inheriting from Xamarin.Forms Label and DO NOT PUT TapGestureRecognizer everywhere the label is required.
public class ExtendedLabel : Label
{
private event EventHandler click;
public string Name
{
get; set;
}
public void DoClick()
{
click?.Invoke(this, null);
}
public event EventHandler Clicked
{
add
{
lock (this)
{
click += value;
var g = new TapGestureRecognizer();
g.Tapped += (s, e) => click?.Invoke(s, e);
GestureRecognizers.Add(g);
}
}
remove
{
lock (this)
{
click -= value;
GestureRecognizers.Clear();
}
}
}
}
In your XAML file you import the namespace where the control is defined, e.g.
<ContentPage xmlns:ctrl="clr-namespace:UICore.Controls" ...
And use it as ordinary control:
<ctrl:ExtendedLabel x:Name="quitButton" Clicked="OnQuit">
MyClickyLabel.GestureRecognizers.Add(
new TapGestureRecognizer() {
Command = new Command(() => {
/* Handle the click here */
} )
}
);
Hi i have a weird problem.
I defined few labels and textbox for data entry purpose using xamarin.forms.
I wrapped them into scroll view so that when keyboard appears, they should scroll.
It is working fine. The control which has focus scroll to top and the keyboard appears when it get focus. but i also have couple of buttons at the bottom of my form. Now, the problem is, whenever keyboard appears, my bottom buttons are also scrolled. which looks weird. As button are for submit or cancel, it should be stay there in bottom.
following is my code:
var firstNameLabel = new Label { HorizontalOptions = LayoutOptions.Fill };
firstNameLabel.Text = "First Name";
var firstName = new Entry() { HorizontalOptions = LayoutOptions.FillAndExpand };
firstName.SetBinding (Entry.TextProperty,MyViewModel.FirstNamePropertyName);
var lastNameLabel = new Label { HorizontalOptions = LayoutOptions.Fill};
lastNameLabel.Text = "Last Name";
var lastName = new Entry() { HorizontalOptions = LayoutOptions.FillAndExpand };
lastName.SetBinding (Entry.TextProperty, MyViewModel.LastNamePropertyName);
---- other fields
Button btnSubmit = new Button
{
HorizontalOptions = LayoutOptions.Fill,
BackgroundColor = Color.FromHex("#22498a"),
TextColor = Color.White,
Text = "Submit"
};
var cancelButton = new Button { Text = Cancel", BackgroundColor = Color.FromHex("0d9c00"), TextColor = Color.White };
contactUsButton.Clicked += (object sender, EventArgs e) =>
{
// cancel operation
};
var cotrolStakeLayout = new StackLayout () {
Padding = new Thickness(Device.OnPlatform(5, 5, 5),0 , Device.OnPlatform(5, 5, 5), 0), //new Thickness(5,0,5,0),
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.Fill,
Orientation = StackOrientation.Vertical,
Children = { firstNameLabel, firstName, lastNameLabel, lastName, -- and other fields}
};
var scrollableContentLayout = new ScrollView (){
Content = cotrolStakeLayout,
Orientation = ScrollOrientation.Vertical,
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill
};
var buttonLayout = new StackLayout (){
Padding = new Thickness(Device.OnPlatform(5, 5, 5),0 , Device.OnPlatform(5, 5, 5), 0), //new Thickness(5,0,5,0),
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
Orientation = StackOrientation.Vertical,
Children= { btnSubmit , cancelButton }
};
var nameLayout = new StackLayout()
{
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
Orientation = StackOrientation.Vertical,
Children = {scrollableContentLayout,buttonLayout}
};
return nameLayout;
Any ideas what is wrong with it?
You have to change your layout to reach your target:
- Define a "Main-StackLayout"
- Create a "Button-StackLayout" for your Buttons (that should stay on top)
- Add your Buttons to the "Button-StackLayout"
- Add the "button-StackLayout to the "Main-StackLayout"
- Add the ScrollView to to "Main-StackLayout"
- Set content of the page to the "Main-StackLayout"
This should work: buttons stays on top, where (only) the ScrollView can be scrolled.