ScrollView Overlap - xamarin

I try to put a ScrollView with a StackLayout between two StackLayouts but when I scroll the elements inside the ScrollView, the items always overlap the superior StackLayout as seen in the image:
The code I use is:
stackPrinc = new StackLayout()
{
Spacing = 0,
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = {
ly_sup,
new ScrollView() { Content = ly_main, IsClippedToBounds = true, BackgroundColor = Color.Olive },
ly_inf },
};

I solved it, its a bug happends when the scrollview got a elemen over and under him. My new code is;
stackPrinc = new StackLayout()
{
Spacing = 0,
Children = {
ly_sup,
new StackLayout() { Children = { new ScrollView() { Content = ly_main, IsClippedToBounds = true, BackgroundColor = Color.Aqua, } } },
ly_inf,
},
};

Related

Binding .Bind(TapGestureRecognizer.CommandProperty, nameof(BackArrowTapped)); to a grid doesn't call my BackArrowTapped command

I have this code:
public ScrollHeadingView2()
{
outerGrid = new Grid() { BackgroundColor = Color.Red, RowSpacing = 0, ColumnSpacing = 0 };
outerGrid.AddChild(new BoxView()
{
HeightRequest = 100,
WidthRequest = 100,
BackgroundColor = Color.Pink
}, 0, 0);
var tap1 = new TapGestureRecognizer()
{
NumberOfTapsRequired = 1
}.Bind(TapGestureRecognizer.CommandProperty, nameof(BackArrowTapped));
grid1.GestureRecognizers.Add(tap1);
}
private async Task BackArrowTapped()
{
await Shell.Current.Navigation.PopAsync(false);
}
The pink area of the grid displays but when I place a break on the await then it doesn't go there when I tap that area.
Does anyone have any idea what might be wrong?
BackArrowTapped is not a command. If you want to use an event handler, just set the gesture's Tapped property
tap1.Tapped += async (s,o) => { await BackArrowTapped(); };

Xamarin Forms - TapGestureRecognizer.CommandParameterProperty not working

I'm creating a Grid programmatically, and i want to add a Tap Gesture Recognizer to each layout, and passing some parameters with it. I'm using MVVM pattern.
Here is how i'm doing this :
public SelectProfileViewModel()
{
_userGrid = new Grid();
_userGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
_userGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
_userGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = 150 });
_userGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = 150 });
_userGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = 150 });
_userGrid.Children.Add(createUserView("A"), 0, 0);
_userGrid.Children.Add(createUserView("B"), 1, 0);
_userGrid.Children.Add(createUserView("C"), 0, 1);
_userGrid.Children.Add(createUserView("D"), 1, 1);
_userGrid.Children.Add(createUserView("E"), 2, 0);
}
private View createUserView(string name)
{
var parentView = new StackLayout { HorizontalOptions = LayoutOptions.Center };
parentView.Children.Add(new Image { Source = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ1Gevu4Tk803Ydc4VywH_ANoJSf3B6rnuI64IChMJSdw9qfR7s", HorizontalOptions = LayoutOptions.Center } );
parentView.Children.Add(new Label { Text = name, HorizontalOptions = LayoutOptions.Center } );
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandProperty, "SelectProfileCommand");
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandParameterProperty, name);
parentView.GestureRecognizers.Add(tapGestureRecognizer);
return parentView;
}
When i click on the child view, the command is well called. But the parameter is null.
Here is the command and parameter part :
public ICommand SelectProfileCommand => new Command<string>(async (name) => await SelectProfileAsync(name));
private async Task SelectProfileAsync(string name)
{
await NavigationService.NavigateToAsync<LoginViewModel>(name);
}
Anyone has an idea of what's happening ?
Thanks.
Binding refers to a property. So you are trying to bind to properties called A, B, C, .... If this should work, you have to have properties with these names in your binding context.
If you just want to set the parameter to a constant value you can do it by changing
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandParameterProperty, name);
// to
tapGestureRecognizer.CommandParameter = name;

How can I access objects from a xaml that I create in cs code?

I'm trying to access some objects that I create with cs (carousel pages with labels, listview and buttons) but I have not had success.
Here reference this by saying that you can work with classId or styleId, but it does not make it very clear how to get the same:
https://developer.xamarin.com/guides/xamarin-forms/xaml/xaml-basics/getting_started_with_xaml/
Here you can see the carousel pages
This is my cs code:
private readonly List<AreaModel> _are = new List<AreaModel>();
public AreasModal()
{
Lista();
}
protected override void OnCurrentPageChanged()
{
base.OnCurrentPageChanged();
var index = Children.IndexOf(CurrentPage);
}
private async void Lista()
{
var listareas = await App.NaturalezaManager.GetAreas();
foreach (var Area in listareas) {
var areas = new AreaModel
{
IdArea = Area.IdArea,
NombreArea = Area.NombreArea
};
_are.Add(areas);
Button boton = new Button
{
Text = "Listo",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand
};
Children.Add(new ContentPage
{
Content = new StackLayout
{
Children =
{
new StackLayout
{
Orientation = StackOrientation.Horizontal,
Children =
{
new StackLayout
{
Orientation = StackOrientation.Vertical,
Children =
{
new Label
{
Text = Area.NombreArea,
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand
}
}
},
new Switch
{
HorizontalOptions = LayoutOptions.EndAndExpand
}
}
},
new ListView
{
ItemsSource = listareas,
ItemTemplate = new DataTemplate(() =>
{
Label nameLabel = new Label
{
HorizontalOptions = LayoutOptions.FillAndExpand
};
nameLabel.SetBinding(Label.TextProperty,"NombreArea");
Switch switcher = new Switch
{
HorizontalOptions = LayoutOptions.EndAndExpand
};
return new ViewCell
{
View = new StackLayout
{
Orientation = StackOrientation.Horizontal,
Children =
{
new StackLayout
{
Orientation = StackOrientation.Vertical,
Children =
{
nameLabel
}
},
switcher
}
}
};
})
},
boton
}
}
});
}
}
}
I have to access these objects from the "OnCurrentPageChanged" method but I have no idea how to do it, since if it were xaml code could be obtained with the property x:Name, in advance thanks for the help.

Xamarin forms animation does not repeat

I am trying to animate an Image in Xamarin.Forms (version 2.3.3.168). The animation is working, but it does not repeat.
public class WelcomePage : ContentPage
{
Image img;
public WelcomePage()
{
img = new Image
{
Source = "img.png",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
};
Content = new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Children = {
img
}
};
}
protected override void OnAppearing()
{
base.OnAppearing();
var a = new Animation();
a.Add(0, 0.5, new Animation((v) =>
{
img.Scale = v;
}, 1.0, 1.2, Easing.CubicInOut, () => { System.Diagnostics.Debug.WriteLine("ANIMATION A"); }));
a.Add(0.5, 1, new Animation((v) =>
{
img.Scale = v;
}, 1.2, 1.0, Easing.CubicInOut, () => { System.Diagnostics.Debug.WriteLine("ANIMATION B"); }));
a.Commit(img, "animation", 16, 2000, Easing.Linear, (d, f) => img.Scale = 1.0, () =>
{
System.Diagnostics.Debug.WriteLine("ANIMATION ALL");
return true;
});
}
}
After running the app for a few seconds, the following debug output is printed:
ANIMATION A
ANIMATION B
ANIMATION ALL
ANIMATION ALL
ANIMATION ALL
I am testing this as a UWP.
According to this thread on the Xamarin forums, others seem to be have the same issue. It seems related to a private property being set in each of the sub-animations.
A workaround is to recreate the animation chain each time the chain completes:
public class WelcomePage : ContentPage
{
Image img;
public WelcomePage()
{
img = new Image
{
Source = "circle_plus.png",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
};
Content = new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Children = {
img
}
};
}
protected override void OnAppearing()
{
base.OnAppearing();
animate();
}
void animate()
{
var a = new Animation();
a.Add(0, 0.5, new Animation((v) =>
{
img.Scale = v;
}, 1.0, 1.2, Easing.CubicInOut, () => { System.Diagnostics.Debug.WriteLine("ANIMATION A"); }));
a.Add(0.5, 1, new Animation((v) =>
{
img.Scale = v;
}, 1.2, 1.0, Easing.CubicInOut, () => { System.Diagnostics.Debug.WriteLine("ANIMATION B"); }));
a.Commit(img, "animation", 16, 2000, null, (d, f) =>
{
img.Scale = 1.0;
System.Diagnostics.Debug.WriteLine("ANIMATION ALL");
animate();
});
}
}

Grid not resizing when child's visibility is changed

I have a Xamarin app with a Grid, where there is a Label and an Entry.
When I change the Entry’s text, I want the Label to be visible, and if it is empty, it shall not show the Label.
I have created a demo-app to verify, that it does not have anything to do with my code. But the following code also fails
MainPage = new ContentPage
{
Content = new Grid
{
ColumnDefinitions = new ColumnDefinitionCollection
{
new ColumnDefinition { Width = new GridLength(1,GridUnitType.Auto) },
new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }
}
}
};
Label label;
Entry entry;
Grid mainGrid = ((Grid)((ContentPage)MainPage).Content);
mainGrid.Add(btnDelete = new MR.Gestures.StackLayout
{
Children = {
new ExtendedLabel { Style = Styles.LargeLabelIcon, Text = "\ue634", TextColor = Color.Black }
},
WidthRequest = 50
}, 0, 0);
mainGrid.Children.Add(label = new Label { Text = "TEST", IsVisible = false }, 0, 0);
mainGrid.Children.Add(entry = new Entry { }, 1, 0);
entry.TextChanged += (sender, arg) => label.IsVisible = entry.Text.Length > 0;
Does anybody have an idea of how to fix it?
I am not sure if this is what your are trying to achieve:
MainPage = new ContentPage
{
Content = new Grid
{
ColumnDefinitions = new ColumnDefinitionCollection
{
new ColumnDefinition { Width = new GridLength(1,GridUnitType.Auto) },
new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }
}
}
};
Label label;
Entry entry;
Grid mainGrid = ((Grid)((ContentPage)MainPage).Content);
mainGrid.Children.Add(label = new Label {
Text = "TEST",
IsVisible = false,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Start,
}, 0, 0);
mainGrid.Children.Add(entry = new Entry {
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.Black,
TextColor = Color.White
}, 1, 0);
entry.TextChanged += (sender, arg) => label.IsVisible = entry.Text.Length > 0;
I have added vertical and horizontal options to the controllers.
I just had a very similar issue. After the text on my child component was changed, it would be cut-off.
The problem turned out to be that you can't mix a ColumnDefinition of * on the grid with a HorizontalOptions on the child. Having both seems to break something. Replacing it with HorizontalTextAlignment fixed it for me.
Maybe this will help someone else someday.

Resources