XAML/MVVMx Problems with binding custom Array of object to a Grid - xamarin

I try to bind an Object with custom Text for testing to my GridView and can't really get the solution.
I already tried to get it rolling with Grid.BindingContext but it won't work.
Can someone help me out here?
<Grid>
<Grid.BindingContext>
<x:Array Type="{x:Type clients:MinRepresentation}<clients:MinRepresentation Id="123456789" PlannedStartTime="01-01-2019" PlannedEndTime="01-12-2019" />
</x:Array>
</Grid.BindingContext>
<StackLayout Orientation="Horizontal" Padding="0,10,0,5" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" BackgroundColor="#CC3F6E3F">
<Image Source="{helpers:ImageResource catkinApp.UI.Images.state_new.png}" Margin="10,0,0,0" />
<Label Text="{Binding ID, StringFormat='ID: [{0}]'}" FontSize="Small" Margin="5,0,10,0" FontAttributes="Bold" TextColor="#FFFFFF"/>
<Label HorizontalTextAlignment="End" Text="(In Bearbeitung)" FontSize="Small" FontAttributes="Bold" TextColor="#FFFFFF"/>
</StackLayout>
</Grid>

According to your description, you want to bind custom object for Grid.BindingContext, you don't need to use Array, you just do like this:
public class model1
{
public string str1 { get; set; }
public string str2 { get; set; }
}
<Grid>
<Grid.BindingContext>
<local:model1 str1="aaaa" str2="bbbb"></local:model1>
</Grid.BindingContext>
<StackLayout Orientation="Vertical">
<Label Text="this is test, please take a look!" />
<Label
Margin="5,0,10,0"
FontAttributes="Bold"
FontSize="Small"
Text="{Binding str1}"
TextColor="#FFFFFF" />
<Label
FontAttributes="Bold"
FontSize="Small"
Text="{Binding str2}"
TextColor="#FFFFFF" />
</StackLayout>
</Grid>
Here is the article from MSDN, you can take a look:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/string-formatting

Related

How to get value of swiped card view xamarin

I have a SwipeCardView and I want to get the id of the user that I've just swiped.
<swipeCardView:SwipeCardView
x:Name="SwipeView1" ItemsSource="{Binding Profiles}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
Padding="10" >
<swipeCardView:SwipeCardView.ItemTemplate>
<DataTemplate>
<StackLayout HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Frame CornerRadius="10"
Padding="8"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<AbsoluteLayout>
<AbsoluteLayout.GestureRecognizers>
<SwipeGestureRecognizer Direction="Left" Command="{Binding LeftCommand}"
CommandParameter="{Binding nome}" />
</AbsoluteLayout.GestureRecognizers>
<Image Source="{Binding foto_perfil}"
Aspect="AspectFill"
AbsoluteLayout.LayoutBounds=".5,0.5,1,1"
AbsoluteLayout.LayoutFlags="All" />
<Label FontSize="Large"
WidthRequest="30"
FontAttributes="Bold"
TextColor="White"
BackgroundColor="Black"
AbsoluteLayout.LayoutBounds="0.1,0.95,250,30"
AbsoluteLayout.LayoutFlags="PositionProportional">
<Label.FormattedText>
<FormattedString>
<Span Text="{Binding nome}" />
<Span Text=", " />
<Span Text="{Binding data_nasc}" />
</FormattedString>
</Label.FormattedText>
</Label>
</AbsoluteLayout>
</Frame>
</StackLayout>
</DataTemplate>
</swipeCardView:SwipeCardView.ItemTemplate>
</swipeCardView:SwipeCardView>
In the C# I created a command but it never enter i the void:
public Command LeftCommand => new Command<string>(LeftSwipe);
void LeftSwipe(string parameter)
{
var variable = parameter; //= breed_Name
DisplayAlert("", variable.ToString(), "ok");
}
I donĀ“t know what I've done wrong because it still swipes
If your LeftCommand is in the ViewModel of your page, you can specify a source just as Jason said.
You can refer to the folloing code:
<swipeCardView:SwipeCardView x:Name="mCardView"
ItemsSource="{Binding CardItems}"
VerticalOptions="FillAndExpand">
<swipeCardView:SwipeCardView.ItemTemplate>
<DataTemplate>
<StackLayout >
<Label Text="{Binding Name}" FontSize="Large" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" BackgroundColor="Beige" />
<StackLayout.GestureRecognizers>
<SwipeGestureRecognizer Direction="Left"
Command="{Binding Path=BindingContext.LeftCommand, Source={x:Reference mCardView}}"
CommandParameter="{Binding .}" >
</SwipeGestureRecognizer>
</StackLayout.GestureRecognizers>
</StackLayout>
</DataTemplate>
</swipeCardView:SwipeCardView.ItemTemplate>
</swipeCardView:SwipeCardView>
Note:
1.mCardView is the x:Name="mCardView" of your SwipeCardView;
2.In your viewModel, you can get the Binded Item as follows:
public Command LeftCommand => new Command(LeftSwipe);
void LeftSwipe(Object parameter)
{
//You can change `Profile ` to your Item Model
Profile variable = parameter as Profile;
System.Diagnostics.Debug.WriteLine("-----------> " + variable.Name +"<---> Id = "+ variable.ProfileId);
}

Xamarin - ImageButton doesnt activate every click

Screen
On the picture above you can see where the ImageButton sometimes activates. When I spam clicking in the blue area the counter sometimes increases. I think there might be another Layer on top of the ImageButton but I dont know how to fix it. Below there is the XAML code. Hopefully somebody can help. Thanks!
<StackLayout>
<Label Text="Discover" TextColor="Black" FontSize="24" FontAttributes="Bold" Margin="15" />
<CarouselView ItemsSource="{Binding plants}" HeightRequest="300" PeekAreaInsets="100">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame HeightRequest="280" WidthRequest="180" BackgroundColor="Wheat" HasShadow="True" Margin="10" Padding="0" HorizontalOptions="CenterAndExpand" CornerRadius="10" >
<Grid>
<StackLayout>
<ImageButton Source="{Binding imgsource}" VerticalOptions="FillAndExpand"
Aspect="AspectFill" Opacity="0.8" Clicked="ImageButton_Clicked"/>
</StackLayout>
<StackLayout Margin="0,10" >
<Image Source="https://icons-for-free.com/iconfiles/png/512/bookmark-131964752402712733.png" HeightRequest="35"
Aspect="AspectFit" HorizontalOptions="EndAndExpand" Margin="5,-15"/>
<Label Text="{Binding name_norm}" TextColor="Black" FontSize="16" FontAttributes="Bold"
Margin="15,-10,0,0" VerticalOptions="EndAndExpand" />
<StackLayout Orientation="Horizontal" Margin="15,-8,0,0" >
<Image Source="https://www.freeiconspng.com/thumbs/info-icon/info-icon-24.png" HeightRequest="15"
Aspect="AspectFit"/>
<Label Text="{Binding name_lat}" TextColor="Black" FontSize="16" FontAttributes="Italic" VerticalOptions="EndAndExpand" Margin="-5,0" />
</StackLayout>
</StackLayout>
</Grid>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<Label x:Name="label" Text="0 ImageButton clicks"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
Here the C# Code:
namespace PlantBase
{
public partial class MainPage : ContentPage
{
int clickTotal;
public MainPage()
{
InitializeComponent();
}
private void ImageButton_Clicked(object sender, EventArgs e)
{
clickTotal += 1;
label.Text = $"{clickTotal} ImageButton click{(clickTotal == 1 ? "" : "s")}";
}
}
}
Check VisualElement.InputTransparent Property.
false if the element and its children should receive input; true if neither the element nor its children should receive input and should, instead, pass inputs to the elements that are visually behind the current visual element. Default is false.
What you need is to set InputTransparent to true on the text stackLayout .
<StackLayout InputTransparent="True" Margin="0,10" VerticalOptions="EndAndExpand" BackgroundColor="SaddleBrown">
<Label Text="{Binding name_norm}" TextColor="White" FontSize="16" FontAttributes="Bold" Margin="15,-10,0,0" VerticalOptions="EndAndExpand" />
<StackLayout Orientation="Horizontal" Margin="15,-8,0,0" BackgroundColor="Aqua">
<Image Source="https://www.freeiconspng.com/thumbs/info-icon/info-icon-24.png" HeightRequest="15" Aspect="AspectFit" />
<Label Text="{Binding name_lat}" TextColor="White" FontSize="16" FontAttributes="Italic" VerticalOptions="EndAndExpand" Margin="-5,0" />
</StackLayout>
</StackLayout>
Okay I found the Problem. It was that before I put the red Flag on the Top and the text at the bottom in one Stacklayout which expanded from top to bottom. Now that i put them in seperate StackLayouts it works and the ImageButton is free.
Pictures before/after.
old StackLayout
new Stacklayout
The new XAML is:
<CarouselView ItemsSource="{Binding plants}" HeightRequest="300" PeekAreaInsets="100">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame HeightRequest="280" WidthRequest="180" BackgroundColor="Wheat" HasShadow="True" Margin="10" Padding="0" HorizontalOptions="CenterAndExpand" CornerRadius="10" >
<Grid>
<StackLayout>
<ImageButton Source="{Binding imgsource}" VerticalOptions="FillAndExpand"
Aspect="AspectFill" Opacity="0.9" Clicked="ImageButton_Clicked" />
</StackLayout>
<StackLayout VerticalOptions="StartAndExpand" HorizontalOptions="EndAndExpand" BackgroundColor="Aqua">
<ImageButton Source="https://icons-for-free.com/iconfiles/png/512/bookmark-131964752402712733.png" HeightRequest="35"
Aspect="AspectFit" HorizontalOptions="EndAndExpand" Margin="5,0" BackgroundColor="Transparent" Clicked="ImageButton_Clicked_1" />
</StackLayout>
<StackLayout Margin="0,10" VerticalOptions="EndAndExpand" BackgroundColor="SaddleBrown">
<Label Text="{Binding name_norm}" TextColor="White" FontSize="16" FontAttributes="Bold"
Margin="15,-10,0,0" VerticalOptions="EndAndExpand" />
<StackLayout Orientation="Horizontal" Margin="15,-8,0,0" BackgroundColor="Aqua" >
<Image Source="https://www.freeiconspng.com/thumbs/info-icon/info-icon-24.png" HeightRequest="15"
Aspect="AspectFit" />
<Label Text="{Binding name_lat}" TextColor="White" FontSize="16" FontAttributes="Italic" VerticalOptions="EndAndExpand" Margin="-5,0" />
</StackLayout>
</StackLayout>
</Grid>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
New Question now. Since at the bottom there is the Text StackLayout, where the Text is I cant press the ImageButton. How can I put the ImageButton as top "layer" so I can also press it while pressing on the text.

i want to get a parameter with button in xaml

i want to delete or update rows of a list view by the primary key which is Label
<Label Grid.Column="1"
Grid.Row="0"
Text="{Binding Label}"
FontSize="20"
TextColor="Black"
Margin="0,10"
FontFamily="Comfortaa-Light"/>
<Label Grid.Column="2"
Grid.Row="1"
Text="{Binding Todo}"
FontSize="20"
TextColor="Black"
Margin="0,10,0,0"
FontFamily="Comfortaa-Light"
HorizontalOptions="Start"
VerticalOptions="Center"/>
<ImageButton Grid.Column="2"
Grid.Row="0"
HorizontalOptions="End"
VerticalOptions="End"
Source="plus.png"
Margin="9"
BackgroundColor="Transparent"
Clicked="AddReminder"
here parameter{{Binding Label}} />
I need help and thank you
Since you had used Data-binding(MVVM) .It would better to handle the logic by using Command . In addition, we could pass the text of label(or the whole model) instead of the Label itself .
<?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="App11.MainPage"
x:Name="page"> // set the name of the page
<ImageButton Grid.Column="2"
Grid.Row="0"
HorizontalOptions="End"
VerticalOptions="End"
Source="plus.png"
Margin="9"
BackgroundColor="Transparent"
Command="{Binding Source={x:Reference page},Path=BindingContext.xxxCommand}}"
CommandParameter="{Binding .}"
/>
in your viewmodel
public ICommand xxxCommand { get; set; }
xxxCommand = new Command((arg)=> {
//var model = arg as YourModel;
// you can get the text of label from the model and do something you want
});

Xamarin.Forms: can grid cell include several labels?

One of the grid cells looks like this:
<Label Text="{Binding Address1}" FontSize="12" TextColor="Black" Grid.Row="1" Grid.Column="0"/>
This displays Address1 which is correct.
But instead of just showing Address1, I would like to display Address1, City, St, each with a different FontSize.
Can this be done without altering the number of rows and columns in the grid?
One way is to place a StackLayout at the Grid row|column and then separately format each element within it:
<Grid....
~~~
<StackLayout Grid.Row="1" Grid.Column="0">
<Label Text="{Binding Address1}" FontSize="12" TextColor="Black" />
<StackLayout Orientation="Horizontal" >
<Label Text="{Binding City}" FontSize="10" TextColor="Black" />
<Label Text="{Binding St}" FontSize="10" TextColor="Black" />
</StackLayout>
<StackLayout>
~~~
</Grid>
Sure, you would use:
<StackLayout Grid.Row="1" Grid.Column="0">
<Label Text="l1"/>
<Label Text="l2"/>
<Label Text="l3"/>
</StackLayout>
You can use other layouts such as StackLayout inside of your Grid as others suggested but you can also put multiple Views inside a Grid cell by setting the same Grid.Row and Grid.Column for them and by setting HorizontalOptions and VerticalOptions of views inside the Grid you can choose each view position.
For Example:
<Grid....
~~~
<Label Grid.Row="0" Grid.Column="1" HorizontalOptions="Start" VerticalOptions="Start" Text="{Binding Address1}" FontSize="12" TextColor="Black" />
<Label Grid.Row="0" Grid.Column="1" HorizontalOptions="Start" VerticalOptions="End" Text="{Binding City}" FontSize="10" TextColor="Black" />
<Label Grid.Row="0" Grid.Column="1" HorizontalOptions="End" VerticalOptions="End" Text="{Binding St}" FontSize="10" TextColor="Black" />
~~~
</Grid>

How can I create a label inside a ViewCell that when clicked will call a method?

I have this code:
<ViewCell x:Name="ss" Height="50">
<Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
<Label Style="{DynamicResource ListItemTextStyle}" HorizontalOptions="StartAndExpand" VerticalOptions="Center" Text="Category Group" />
<Switch x:Name="ssSwitch" HorizontalOptions="End" VerticalOptions="Center" Grid.Column="1" Toggled="SsSwitch" />
</Grid>
</ViewCell>
I would like to extend this with another row and a label with the text of "Clear Deck"
How can I add a label for this that when clicked will call a method?
Here's a simple example of how to do it. You just need to add a Label with a TapGestureRecognizer. Then you need to implement ClearLabelTapped in the code behind.
<ViewCell x:Name="ss" Height="50">
<StackLayout Orientation="Vertical">
<Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
<Label Style="{DynamicResource ListItemTextStyle}" HorizontalOptions="StartAndExpand" VerticalOptions="Center" Text="Category Group" />
<Switch x:Name="ssSwitch" HorizontalOptions="End" VerticalOptions="Center" Grid.Column="1" Toggled="SsSwitch" />
</Grid>
<Label Text="Clear Deck">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="ClearLabelTapped" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
Code behind:
public void ClearLabelTapped(object sender, EventArgs args)
{
// This is called when you tab the "Clear Deck" label
}
Please notice that using view models and commands would be a better way to do this (separation of concerns) but I wanted to keep this simple. Refer to the official documentation on how to work with the TapGestureRecognizer.

Resources