I'm new to Xamarin development and I'm hopeful there's a quick fix for this seemingly easy issue.
My Environment
Xamarin Studio Community on Mac 6.1.3 (build 19)
Xamarin.Android 7.0.2.42
Xamarin.Ios 10.3.1.7
Xcode 8.2.1
Mac OSX 10.12.1
My Issue
I have an existing xaml file from my Visual Studio Online repo. I added an x:name attribute called lblSearchText to a label control so I can access it in code behind. Code behind for the xaml allows me to access this control by the name I added without issue. However, when compiling I get
The name ‘lblSearchText’ does not exist in the current context
I’ve confirmed the following
Build Action on the XAML file is EmbeddedResource
Custom Tool property on the XAML file is MSBuild:UpdateDesignTimeXaml
My XAML EDIT: added full XAML
<?xml version="1.0" encoding="UTF-8" ?>
<common:ContentPage x:Class="MyApp.SearchAuthenticatedPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:common="clr-namespace:MyApp.Common;assembly=MyApp.Common"
xmlns:commonView="clr-namespace:MyApp.Common.Views;assembly=MyApp.Common"
xmlns:help="clr-namespace:MyApp.Helpers;assembly=MyApp"
xmlns:helpersCommon="clr-namespace:MyApp.Helpers;assembly=MyApp.Common"
xmlns:local="clr-namespace:MyApp;assembly=MyApp"
xmlns:sty="clr-namespace:MyApp.Styles;assembly=MyApp">
<common:ContentPage.Resources>
<ResourceDictionary>
<local:DistanceToStringConverter x:Key="DistanceToString" />
<local:StringToHeaderConverter x:Key="StringToHeader" />
<local:StringToUpperConverter x:Key="StringToUpper" />
<local:IsFavoriteToBackgroundColorConverter x:Key="IsFavoriteToBackgroundColor" />
</ResourceDictionary>
</common:ContentPage.Resources>
<RelativeLayout BackgroundColor="White" Padding="0">
<common:SearchBar x:Name="searchBar"
Title="{helpersCommon:Translate searchBarText}"
ClickCommand="{Binding SearchCommand}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=Constant, Constant=50}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=X}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Y}" />
<AbsoluteLayout IsVisible="{Binding IsMapVisible}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Constant=-50}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=X}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Y, Constant=50}">
<commonView:MapView x:Name="map"
WidthRequest="500"
HeightRequest="500"
VerticalOptions="FillAndExpand"
AbsoluteLayout.LayoutBounds="1,1,1,1"
AbsoluteLayout.LayoutFlags="All"
DirectionLocation="{ Binding DirectionLocation}"
IsVisible="{Binding IsMapVisible}"
Location="{Binding CurrentLocation}"
ShowDirection="{ Binding IsShowingDirection}"
Source="{Binding GetMapSource}"
ZoomToLocation="true" />
<Button x:Name="getDirectionButton"
AbsoluteLayout.LayoutBounds=".28,.33,100,30"
AbsoluteLayout.LayoutFlags="PositionProportional"
BackgroundColor="Transparent"
Text="" />
<Button x:Name="storeDetailsButton"
AbsoluteLayout.LayoutBounds=".70,.33,100,30"
AbsoluteLayout.LayoutFlags="PositionProportional"
BackgroundColor="Transparent"
IsVisible="false"
Text="" />
<Button x:Name="phoneButton"
AbsoluteLayout.LayoutBounds=".28,.27,100,20"
AbsoluteLayout.LayoutFlags="PositionProportional"
BackgroundColor="Transparent"
Text="" />
</AbsoluteLayout>
<ListView x:Name="list"
HeightRequest="300"
CachingStrategy="RetainElement"
Footer="{Binding .}"
HasUnevenRows="true"
IsGroupingEnabled="true"
IsVisible="{Binding IsListVisible}"
ItemsSource="{Binding FinalSearchResult}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Constant=-47}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=X}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Y, Constant=47}"
SeparatorColor="Transparent"
SeparatorVisibility="None">
<ListView.FooterTemplate>
<DataTemplate>
<ContentView>
<Label x:Name="lblSearchText" <!--- My Control --->
Margin="13, 10"
HorizontalOptions="Center"
IsVisible="{Binding IsEmpty}"
Style="{x:Static sty:Styles.PatientListBigLabelStyle}"
Text="{helpersCommon:Translate searchText}"
VerticalTextAlignment="Center" />
</ContentView>
</DataTemplate>
</ListView.FooterTemplate>
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="{Binding Favorite, Converter={StaticResource IsFavoriteToBackgroundColor}}" Padding="13,15">
<Label Style="{x:Static sty:Styles.DarkLabelStyle}" Text="{Binding GroupName}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid BackgroundColor="{Binding IsFavorite, Converter={StaticResource IsFavoriteToBackgroundColor}}"
Padding="13,16"
RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="5" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="35" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<commonView:FavoriteButton Grid.Row="0"
Grid.Column="0"
Margin="0,0,7,0"
ClickCommand="{Binding FavoriteChangedCommand}"
IsFavorite="{Binding IsFavorite}"
Style="{x:Static sty:Styles.FavoriteButtonStyle}" />
<Label Grid.Row="0"
Grid.Column="1"
FontSize="{x:Static sty:Styles.VeryLargeFontSize}"
Style="{x:Static sty:Styles.DarkBoldLabelStyle}"
Text="{Binding ShoppingCenterName}" />
<Label Grid.Row="0"
Grid.Column="2"
FontSize="{x:Static sty:Styles.VeryLargeFontSize}"
Style="{x:Static sty:Styles.DarkBoldRightLabelStyle}"
Text="{Binding DistanceInMilesFromLocation, Converter={StaticResource DistanceToString}}" />
<Label Grid.Row="2"
Grid.Column="1"
IsVisible="{Binding IsAddressVisible}"
Style="{x:Static sty:Styles.DarkLabelStyle}"
Text="{Binding Address}" />
<commonView:UnderlinedButton Grid.Row="2"
Grid.RowSpan="3"
Grid.Column="2"
HeightRequest="35"
Command="{Binding ShowDetailCommand}"
IsVisible="{Binding IsNotSomeMode}"
Style="{x:Static sty:Styles.ListUnderlinedButtonStyle}"
Text="{helpersCommon:Translate detailButtonText}"
TextAligment="TopRight" />
<Label Grid.Row="3"
Grid.Column="1"
VerticalOptions="Start"
IsVisible="{Binding IsAddressVisible}"
Style="{x:Static sty:Styles.DarkLabelStyle}"
Text="{Binding Address2}" />
<commonView:UnderlinedButton Grid.Row="4"
Grid.Column="1"
HeightRequest="35"
HorizontalOptions="StartAndExpand"
Command="{Binding CallCommand}"
Style="{x:Static sty:Styles.ListUnderlinedButtonStyle}"
Text="{Binding Phone}"
TextAligment="TopLeft" />
<commonView:ExtendedButton Grid.Row="4"
Grid.RowSpan="2"
Grid.Column="2"
HorizontalOptions="End"
VerticalOptions="Center"
Command="{Binding SomeCommand}"
IsVisible="{Binding IsSomeMode}"
Style="{x:Static sty:Styles.ActionButtonStyle}"
Text="{helpersCommon:Translate ListSomeButtonText}">
<commonView:ExtendedButton.FontSize>
<OnPlatform x:TypeArguments="x:Double"
Android="11"
iOS="13" />
</commonView:ExtendedButton.FontSize>
</commonView:ExtendedButton>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RelativeLayout>
</common:ContentPage>
My Code Behind EDIT - added full code
using System.Linq;
using Xamarin.Forms;
using static MyApp.Helpers.UIHelper;
namespace MyApp
{
public partial class SearchAuthenticatedPage : global::MyApp.Common.ContentPage
{
public SearchAuthenticatedPage()
{
InitializeComponent();
lblSearchText.Text = "hello world!";
}
public bool IsMapShowing { get; set; }
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
var vm = BindingContext as BaseListViewModel;
if (vm != null) {
if (!ToolbarItems.Any()) {
SetSwitchToolbarItem();
}
vm.SetSwitchToolbarItem = SetSwitchToolbarItem;
}
getDirectionButton.IsVisible = false;
storeDetailsButton.IsVisible = false;
phoneButton.IsVisible = false;
map.CalloutShownCommand = new Command(OnShowCallout);
map.CalloutHidedCommand = new Command(OnHideCallout);
}
void OnHideCallout()
{
if (Device.OS == TargetPlatform.iOS) {
return;
}
getDirectionButton.IsVisible = false;
phoneButton.IsVisible = false;
}
void OnShowCallout()
{
if (Device.OS == TargetPlatform.iOS) {
return;
}
getDirectionButton.Command = map.ShowDirectionsCommand;
phoneButton.Command = map.PhoneCallCommand;
getDirectionButton.IsVisible = true;
phoneButton.IsVisible = true;
}
public void SetSwitchToolbarItem(bool isMapClicked = false)
{
var switchCommand = (BindingContext as BaseListViewModel)?.ChangeViewCommand;
var switchItem = ToolbarItems.FirstOrDefault(i => i.Priority == 0);
if (switchItem != null) {
switchItem.Text = isMapClicked ? Localize("titleListView") : Localize("titleMapView");
switchItem.Command = switchCommand;
}
else {
ToolbarItems.Add(new ToolbarItem { Text = Localize("titleMapView"), Command = switchCommand });
}
}
}
}
I think it is because it's inside a template, so it will be repeated for each item in the list and they would all have the same name. This is not possible.
Also, is there any particular reason you want to access it like this? Why not use binding to a property of the objects that you put in the ItemsSource?
Related
I'm having an issue figuring out how to remove an item from my project while using the same button as I use to perform another task. To sum it up, I'm working on a project where I have a bunch of events a user can like/dislike. What I'm having issues with is trying to figure out how to remove the event from my project once the user has liked the event using the 'like' button. Essentially I want the 'like' button to perform 2 things, one being when its pressed setting it to "true" which is already doing that, but also I want it to remove the event from screen once it's liked.
Here is my XAML:
<StackLayout VerticalOptions="FillAndExpand">
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image x:Name="LblEventImage"
Aspect="Fill"
HeightRequest="350" />
<BoxView BackgroundColor="Black"
HeightRequest="350"
Opacity="0.3" />
<Image Source="BackIconOrg.png"
Margin="5,40,0,0"
HorizontalOptions="Start"
VerticalOptions="Start"
Grid.Row="0">
<Image.GestureRecognizers>
<TapGestureRecognizer x:Name="ImgBack" Tapped="backButton_Clicked"/>
</Image.GestureRecognizers>
</Image>
</Grid>
<Frame VerticalOptions="FillAndExpand"
IsClippedToBounds="False"
BackgroundColor="#263A4F"
Margin="0,-40,0,0"
CornerRadius="25"
HasShadow="False">
<StackLayout Margin="0,-50,0,0">
<Grid HeightRequest="200"
VerticalOptions="Start">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="6*"/>
</Grid.ColumnDefinitions>
<StackLayout Grid.Column="0"
Padding="5"
Spacing="5"
Margin="0,40,0,0">
<Label x:Name="LblEventName"
TextColor="#fc4600"
FontSize="Large"
FontFamily="TTBold"
FontAttributes="Bold"/>
<StackLayout Orientation="Horizontal"
Spacing="0">
<Frame BackgroundColor="#8B93A6"
BorderColor="#8B93A6"
Padding="8"
CornerRadius="15">
<Label TextColor="White"
x:Name="LblEventCategory"
FontFamily="TTNorms"/>
</Frame>
</StackLayout>
<StackLayout Orientation="Vertical" Grid.ColumnSpan="3">
<Label x:Name="LblEventCity"
TextColor="White"
FontFamily="TTNorms"/>
<Label x:Name="LblEventState"
TextColor="White"
FontFamily="TTNorms"/>
</StackLayout>
<!--<Label x:Name="LblLanguage"
TextColor="White" />
<Label x:Name="LblDuration"
TextColor="White" />-->
</StackLayout>
</Grid>
<Label Text="Details:"
FontSize="Medium"
Margin="0,20,0,0"
TextColor="White"
FontFamily="TTNorms"/>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.65*" />
<ColumnDefinition Width="0.35*" />
</Grid.ColumnDefinitions>
<Label Text="Scheduled Date:"
TextColor="White"
Grid.Row="0"
Grid.Column="0"
FontFamily="TTNorms"/>
<Label Text="August 20, 2021"
TextColor="#8B93A6"
Grid.Row="1"
Grid.Column="0"
FontFamily="TTNorms"/>
<Label Text="Group Size:"
TextColor="White"
Grid.Row="0"
Grid.Column="1"
FontFamily="TTNorms"/>
<Label x:Name="LblEventGroupSize"
TextColor="#8B93A6"
Grid.Row="1"
Grid.Column="1"
FontFamily="TTNorms"/>
<Label Text="Paid:"
TextColor="White"
Grid.Row="2"
Grid.Column="0"
FontFamily="TTNorms"/>
<Label x:Name="LblEventPay"
TextColor="#8B93A6"
Grid.Row="3"
Grid.Column="0"
FontFamily="TTNorms"/>
</Grid>
<BoxView BackgroundColor="#8B93A6"
HeightRequest="1" />
<Label Text="Description"
TextColor="White"
FontFamily="TTNorms"/>
<Label x:Name="LblEventDescription"
TextColor="#8B93A6"
FontFamily="TTNorms"/>
<StackLayout Orientation="Horizontal"
HorizontalOptions="Center"
VerticalOptions="Center"
Spacing="60"
Margin="0,30,0,0">
<Image Source="LikeButton.png"
HeightRequest="150">
<Image.GestureRecognizers>
<TapGestureRecognizer x:Name="likedevent" Tapped="likeButton_Clicked" />
</Image.GestureRecognizers>
</Image>
<Image Source="DislikeButton.png"
HeightRequest="150">
<Image.GestureRecognizers>
<TapGestureRecognizer x:Name="dislikeevent" Tapped="dislikeevent_Tapped"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
</StackLayout>
</Frame>
</StackLayout>
</ContentPage.Content>
CS:
public partial class MatchDetail : ContentPage
{
private Event event1;
public MatchDetail(int eventId)
{
InitializeComponent();
GetEventDetail(eventId);
}
private async void GetEventDetail(int eventId)
{
event1 = await ApiService.GetEventById(eventId);
LblEventName.Text = event1.Name;
LblEventDescription.Text = event1.Description;
LblEventCity.Text = event1.City;
LblEventImage.Source = event1.FullImageUrl;
LblEventCategory.Text = event1.Category;
LblEventState.Text = event1.State;
LblEventGroupSize.Text = event1.GroupSize.ToString();
LblEventPay.Text = event1.PayTrueFalse;
}
private async void likeButton_Clicked(object sender, EventArgs e)
{
var likedEvent = new Result()
{
Name = LblEventName.Text,
UserId = Preferences.Get("userId", 0),
LikeTrueFalse = "True"
};
if (event1.LikeTrueFalse == "True")
{
//RemoveEvent
}
var response = await ApiService.LikedEvents(likedEvent);
if (response)
{
await DisplayAlert("", "Your event has been liked", "Ok");
}
else
{
await DisplayAlert("Oops", "something went wrong", "cancel");
}
}
private void backButton_Clicked(object sender, EventArgs e)
{
Navigation.PopModalAsync();
}
in your main page
MessagingCenter.Subscribe<object, int>(this, "RemoveEvent", (sender,id) =>
{
// do whatever to remove event "id" here
});
then in your detail page, after you have marked it as a favorite
Messaging.Center.Send<object, int>(this, "RemoveEvent", eventId);
In Xamarin forms with MVVM ; I'm using observable collection for listing my items in the listview. It worked fine. In my listview i have a Label and i need to change the Label value when the user click on that selected list item. It's also working fine. But the problem is, Selected list item Label value changed only after i scroll the listview.
I need to change the selected list item's Label value On time.
Here is my code:
Xaml
<ListView x:Name="Listitem" Grid.Row="2" Grid.ColumnSpan="2" ItemsSource="{Binding States,Mode=TwoWay}" SelectedItem="{Binding YourSelectedItem,Mode=TwoWay}" VerticalOptions="FillAndExpand" HasUnevenRows="true" CachingStrategy="RecycleElement" BackgroundColor="White" >
<ListView.Header>
<Grid BackgroundColor="{StaticResource Accent}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="Country Code" HorizontalOptions="Center" VerticalOptions="Center" TextColor="{StaticResource Primary}" />
<Label Grid.Column="1" Text="Name" HorizontalOptions="Center" TextColor="{StaticResource Primary}" />
<Label Grid.Column="2" Text="Capital" HorizontalOptions="Center" TextColor="{StaticResource Primary}" />
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid VerticalOptions="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="{Binding abbr}" Margin="5" HorizontalOptions="Center" VerticalOptions="Center" FontSize="18" TextColor="{StaticResource Primary}" />
<Label Grid.Column="1" Text="{Binding name}" Margin="5" HorizontalTextAlignment="Start" VerticalOptions="Center" FontSize="18" LineBreakMode="WordWrap" TextColor="{StaticResource Primary}"/>
<Label Grid.Column="2" Text="{Binding capital}" Margin="5" HorizontalTextAlignment="Start" VerticalOptions="Center" FontSize="18" LineBreakMode="WordWrap" TextColor="{StaticResource Primary}"/>
<controls:CheckBox Grid.Column="3" Margin="0, 0, 0, 0" CheckedChanged="Handle_CheckedChanged" BindingContext="{Binding .}" BackgroundColor="Transparent" WidthRequest="40" HeightRequest="30" IsVisible="True" />
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And this is my View model for selected list item;
public TodoItem YourSelectedItem
{
get
{
return _yourSelectedItem;
}
set
{
_yourSelectedItem = value;
_yourSelectedItem.abbr = "Tapped";
OnPropertyChanged("YourSelectedItem");
}
}
Item source property;
private ObservableCollection<TodoItem> _States;
public ObservableCollection<TodoItem> States
{
get { return _States; }
set { _States = value; OnPropertyChanged("States"); }
}
The class TodoItem needs to implement the interface INotifyPropertyChanged and the property abbr needs to be implemented as something like blow:
public string abbr {
get
{
return _abbr;
}
set
{
if (_abbr != value) {
_abbr = value;
OnPropertyChanged("abbr");
}
}
}
I put a ListView and a Label, immediately after it, but on screen, there is a Empty space between the ListView and the Label with the Text ms.
I would like the ListView to expand automatically, when the items are present.
Or is there an ItemsControl, like WPF?
I have this XAML:
<?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="clr-namespace:Forms"
x:Class="Forms.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<local:MyConverter x:Key="MyConverter"></local:MyConverter>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView Orientation="Vertical">
<StackLayout Padding="10,10,10,10">
<Label FontSize="20" FontAttributes="Bold">Cartão de Ponto</Label>
<Label>Nome:</Label>
<Label Text="{Binding Path=Pessoa.Nome}" />
<Label>CPF:</Label>
<Label Text="{Binding Path=Pessoa.CPF}" />
<Grid Padding="0" MinimumHeightRequest="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="35" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="60" />
</Grid.ColumnDefinitions>
<Label FontSize="10" Text="Data" FontAttributes="Bold" VerticalTextAlignment="End" />
<Label FontSize="10" Grid.Column="1" Text="Dia" FontAttributes="Bold" VerticalTextAlignment="End" />
<Label FontSize="10" Grid.Column="2" Text="Hora Entrada" FontAttributes="Bold" VerticalTextAlignment="End" />
<Label FontSize="10" Grid.Column="3" Text="Hora Saída" FontAttributes="Bold" VerticalTextAlignment="End" />
<Label FontSize="10" Grid.Column="4" Text="Horas Trabalhadas" HorizontalTextAlignment="End" FontAttributes="Bold" />
</Grid>
<!-- HeightRequest="0"-->
<ListView x:Name="lv1" ItemsSource="{Binding Path=Pontos}"
VerticalOptions="FillAndExpand"
HasUnevenRows="False"
>
<ListView.Header>
<StackLayout HeightRequest="0" />
</ListView.Header>
<!-- ItemTemplate -->
<ListView.Footer>
<StackLayout HeightRequest="0" />
</ListView.Footer>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="35" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="60" />
</Grid.ColumnDefinitions>
<Label FontSize="12" Text="{Binding Path=Data, StringFormat='{0:dd/MM/yyyy}'}" />
<Label FontSize="12" Grid.Column="1" Text="{Binding Path=DiaSemana}" />
<Label FontSize="12" Grid.Column="2" Text="{Binding Path=HoraEntrada}" />
<Label FontSize="12" Grid.Column="3" Text="{Binding Path=HoraSaida}" />
<Label FontSize="12" Grid.Column="4" Text="{Binding Path=HorasTrabalhadas, Converter={StaticResource MyConverter}}}" />
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!-- Why is this White space on screen? -->
<StackLayout Orientation="Horizontal">
<Label x:Name="lbl1" />
<Label>ms</Label>
</StackLayout>
<Button x:Name="ButtonPegaCartaoPonto" Text="Carregar" />
<Label></Label>
<Label></Label>
</StackLayout>
</ScrollView>
</ContentPage>
But the ListView lv1 does not automatically expand Horizontally to fit the Items.
How to do this?
Set RowHeight property of your ListView and update height of list using code behind in your constructor like this:
lv1.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) =>
{
if (e.PropertyName == "ItemsSource")
{
try
{
if (lv1.ItemsSource != null)
{
var tmp = (IList) lv1.ItemsSource;
lv1.HeightRequest = tmp.Count * lv1.RowHeight;
}
}
catch (Exception ex)
{
}
}
};
OR
You can also put specific heigh based on row height.
lv1.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) =>
{
if (e.PropertyName == "ItemsSource")
{
try
{
if (lv1.ItemsSource != null)
{
var tmp = (IList) lv1.ItemsSource;
lv1.HeightRequest = tmp.Count * 40;
}
}
catch (Exception ex)
{
}
}
};
I am currently working on a Xamarin CrossPlatform project and have implemented a Listview bound to an ObservableCollection. Everything works out fine until I remove an Item from the ListView. The images in the follow up items within the ListView disappear randomly - not all of them and a different amount of them every time. I guess it has something to do with the MemoryStream, but what do I have to change? Here´s the relevant part of my Model that is bound to the ListView:
public string ImageBase64
{
get
{
return imagebase64;
}
set
{
if (imagebase64 != value)
{
imagebase64 = value;
OnPropertyChanged(nameof(ImageBase64));
OnPropertyChanged(nameof(ImageSource));
}
}
}
public ImageSource ImageSource
{
get
{
if (!string.IsNullOrEmpty(imagebase64))
{
return ImageSource.FromStream(() => new MemoryStream(Convert.FromBase64String(imagebase64)));
}
else
{
return null;
}
}
}
Here´s the relevant XAML:
<ListView x:Name="listView" Margin="20" ItemsSource="{Binding}" ItemSelected="OnListItemSelected" HasUnevenRows="True" SeparatorColor="{StaticResource primaryGreen}" SeparatorVisibility="Default">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Margin="0,5,0,5">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="65" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="45" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Grid.RowSpan="3" Margin="-2,-2,-2,-2" Source="{Binding ImageSource}" HorizontalOptions="Start" VerticalOptions="Center" Aspect="AspectFill"/> <!-- This is the displayed Image -->
<Label Margin="10,0,0,0" Grid.Column="1" Grid.Row="0" FontAttributes="Bold" FontSize="18" TextColor="{StaticResource primaryGreen}" Text="{Binding VorNachname}" VerticalTextAlignment="Start" HorizontalTextAlignment="Start"/>
<Label Margin="10,0,0,0" Grid.Column="1" Grid.Row="1" Text="{Binding MediumSelected.Wert, StringFormat='via {0}'}" HorizontalOptions="FillAndExpand" VerticalTextAlignment="Start" HorizontalTextAlignment="Start"/>
<StackLayout Margin="10,0,0,0" Grid.Column="1" Grid.Row="2" Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Label Text="{Binding Alter,StringFormat='Alter: {0}'}" VerticalTextAlignment="Start" HorizontalTextAlignment="Start" HorizontalOptions="Start"/>
</StackLayout>
<StackLayout Margin="0,0,0,-5" Grid.Column="2" Grid.RowSpan="3" Orientation="Vertical" HorizontalOptions="End" VerticalOptions="End">
<Button WidthRequest="40" HeightRequest="40" BackgroundColor="White" BorderWidth="0" BorderColor="White" Image="socialmedia_18.png" Clicked="OnChangeClicked" CommandParameter ="{Binding}" VerticalOptions="EndAndExpand" />
<Button Margin="0,-15,0,0" WidthRequest="40" HeightRequest="40" BackgroundColor="White" BorderColor="White" Image="cancel_18.png" Clicked="OnDeleteClicked" CommandParameter ="{Binding}" VerticalOptions="End" />
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
...and the Code behind:
async void OnDeleteClicked(object sender, EventArgs e)
{
Helper.TrackEvent("PeopleList_OnDeleteClicked");
//Get selected Person
Person person = (Person)((Button)sender).CommandParameter;
//Remove from Model
DBHelper.DBModel.People.Remove(person);
//Update database
App.Database.UpdateWithChildren(DBHelper.DBModel);
}
EDIT:
Resizing the images does not help, same problem. I tried it by binding a testvariable ImageSourceThumb to the ListViewItemImage:
public ImageSource ImageSourceThumb
{
get
{
if (!string.IsNullOrEmpty(imagebase64))
{
return ImageSource.FromStream(() => new MemoryStream(ImageResizer.ResizeImage(Convert.FromBase64String(imagebase64), 64, 64)));
}
else
{
return null;
}
}
}
I had a similar problem. When I loaded or updated my listview not all the images showed up.
I fixed my problem resizing the images. Huge images gived me a outofmemory exception. Resizing those images to a smaller resolution fixed these problems.
I will be able to deselect my item when i click second time on it.
When I tap an item the background color changed to blue. I want that the background gets the default color when I tap second time to the same item from the list.
Here can you find my code but it isn't working.
XAML
<StackLayout Margin="5,0,5,0" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
<Frame Style="{StaticResource StandardFrameStyle}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<ListView x:Name="lst_pickList" ItemSelected="OnItemSelected" ItemTapped="OnItemTapped" ItemsSource="{Binding PickList}" HasUnevenRows="True" Style="{StaticResource StandardListViewStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid x:Name="grd_pickList" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label x:Name="lbl_comment" Text="Comment:" FontAttributes="Bold" Grid.Row="0" Grid.Column="0" VerticalTextAlignment="Center" Style="{StaticResource StandardLabelStyle}" />
<Label x:Name="lbl_itemNo" Text="ItemNo:" FontAttributes="Bold" Grid.Row="0" Grid.Column="2" VerticalTextAlignment="Center" Style="{StaticResource StandardLabelStyle}" />
<Label x:Name="lbl_description" Text="Description:" FontAttributes="Bold" Grid.Row="1" Grid.Column="0" VerticalTextAlignment="Center" Style="{StaticResource StandardLabelStyle}" />
<Label x:Name="lbl_restant" Text="Restant:" FontAttributes="Bold" Grid.Row="1" Grid.Column="2" VerticalTextAlignment="Center" Style="{StaticResource StandardLabelStyle}" />
<Label x:Name="lbl_comment_binding" Text="{Binding Comment}" Grid.Row="0" Grid.Column="1" VerticalTextAlignment="Center" Style="{StaticResource StandardLabelStyle}" />
<Label x:Name="lbl_itemNo_binding" Text="{Binding ItemNo}" Grid.Row="0" Grid.Column="3" VerticalTextAlignment="Center" Style="{StaticResource StandardLabelStyle}" />
<Label x:Name="lbl_description_binding" Text="{Binding Description}" Grid.Row="1" Grid.Column="1" VerticalTextAlignment="Center" Style="{StaticResource StandardLabelStyle}" />
<Label x:Name="lbl_restant_binding" Text="{Binding Restant}" Grid.Row="1" Grid.Column="3" VerticalTextAlignment="Center" Style="{StaticResource StandardLabelStyle}" />
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Frame>
</StackLayout>
CodeBehind
public void OnItemTapped(object sender, ItemTappedEventArgs args)
{
var newSelectedPick = args.Item as Pick;
if(selectedPick != null && selectedPick.Id == newSelectedPick.Id)
{
lst_pickList.SelectedItem = null;
}
else
{
selectedPick = newSelectedPick;
}
}
Create a boolean property on your Pick object named IsSelected ,then Bind it your grd_pickList's BackgroundColor with a converter.
i.e:
//Xaml
<ListView.Resources>
<ResourceDictionary>
<local:BgConverter x:Key="BgConverter"/>
</ResourceDictionary>
</ListView.Resources>
<Grid x:Name="grd_pickList" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="{Binding IsSelected,Converter={StaticResource BgConverter}}" >
//Converter
class BgConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool &&(bool)value)
return Color.Blue;
else
return Color.White;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
//Xaml.cs
public void OnItemTapped(object sender, ItemTappedEventArgs args)
{
var itm = args.Item as Pick;
itm.IsSelected = !itm.IsSelected;
}
Important: Be Sure IsSelected Property Triggers OnPropertyChanged event.