How to align labels differently in listview - c#

I have 2 labels in a ListView.
1st label is an ItemName (with vertical align to start),
and the 2nd label is ItemDescription (with vertical align to end).
What I'm trying to achieve is...
When ItemDescription is empty, I want the ItemName to be vertical align to center
Since I'm new, it will be great if you can also show an example.
This is my Xaml (ItemsPage)
<ContentPage.Content>
<StackLayout>
<ListView ItemsSource="{Binding _items, Mode=TwoWay}" x:Name="lstView" SelectedItem="{Binding SelectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="0,0,8,0" Margin="3,0,3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="7*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageUrl}" Grid.Column="0" Margin="3"></Image>
<Label Text="{Binding ItemName}" MaxLines="1" LineBreakMode="TailTruncation" FontSize="Medium" FontAttributes="Bold"></Label>
<Label Text="{Binding ItemDescription}" MaxLines="1" LineBreakMode="TailTruncation" Grid.Column="1" VerticalTextAlignment="End"></Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>

You can use the IValueConverter
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/converters
<Label Text="{Binding ItemName}" MaxLines="1" LineBreakMode="TailTruncation" FontSize="Medium" FontAttributes="Bold" VerticalTextAlignment="{Binding ItemDescription,Converter={StaticResource checkItemDescription}}"></Label>
Converter
public class AlignmentConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
if(value==null)
return LayoutOptions.Start;
return LayoutOptions.End;
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}

Related

Binding TopItem from SwipeView Xamarin to Collectionview from Viewmodel to Visibility of View

so i dont understand how to bind properly the TargetNullValue from TopItem to the Visibility of my grid View.
"""
<StackLayout HorizontalOptions="Fill" BackgroundColor="Yellow">
<AbsoluteLayout>
<Button x:Name="exit_button" Image="exit.png" Clicked="Exit_button_Clicked"
AbsoluteLayout.LayoutBounds="1,0,50,50" AbsoluteLayout.LayoutFlags="PositionProportional" />
</AbsoluteLayout>
<swipeCardView:SwipeCardView
x:Name="SwipeCardView"
ItemsSource="{Binding Pictures}"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Red"
Padding="10"
SwipedCommand="{Binding SwipedCommand}"
DraggingCommand="{Binding DraggingCommand}"
Threshold="{Binding Threshold}"
SupportedSwipeDirections="{Binding SupportedDraggingDirections}"
SupportedDraggingDirections="{Binding SupportedDraggingDirections}"
AnimationLength="{Binding AnimationLength}"
>
<swipeCardView:SwipeCardView.TopItem>
<Grid IsVisible="{Binding TopItem , Source={x:Reference SwipeCardView}, TargetNullValue={Binding TopItem}}">
<StackLayout>
<Label Text="Keine Bilder mehr vorhanden" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"
FontSize="Large" FontAttributes="Bold" BackgroundColor="AliceBlue"/>
</StackLayout>
</Grid>
</swipeCardView:SwipeCardView.TopItem>
<swipeCardView:SwipeCardView.ItemTemplate>
<DataTemplate>
<Grid ColumnSpacing="0" RowSpacing="0" BackgroundColor="Wheat">
<Grid.Resources>
<valueconverter:ByteArrayToImageSourceConverter x:Key="SourceConverter" />
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="500" />
</Grid.RowDefinitions>
<Image Source="{Binding Image, Converter={StaticResource SourceConverter}}" Aspect="AspectFit" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"/>
</Grid>
</DataTemplate>
</swipeCardView:SwipeCardView.ItemTemplate>
</swipeCardView:SwipeCardView>
</StackLayout>
</ContentPage>
"""
There is clearly a wrong Binding, as i get the Error:
'Xamarin.Forms.Grid' cannot be converted to type 'System.Boolean'
'App1.Models.Pictures' cannot be converted to type 'System.Boolean'
So as i understand from TopItem, it turn to be null, if the Collectionview or Itemsource is null that means no items are left to swipe.
I want to set the Binding to the Top item, so that if there is no item left, thant the View Should be visible
You can use a converter to converter the TopItem into a boolean value.Such as:
public class TopItemToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
TopItem top= value as TopItem;
if(top == null)
return false;
else
return true;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

How I can hide an element when a switch is toggled?(in XAML)

I wish to hide the first two stacklayouts, when the switch for "Current" is toggled. Ty. Here is my code, but now the stacklayouts appear when the switch is toggled. I need the opposite result.
<ViewCell>
<StackLayout Orientation="Horizontal" HorizontalOptions="Fill"
IsVisible="{Binding Source={x:Reference switch}, Path=IsToggled}">
<Label Text="Date From:" />
<DatePicker Date="{Binding SettingsView.DateFrom, Mode=TwoWay}"
HorizontalOptions="End" TextColor="White" FontAttributes="Bold"/>
</StackLayout>
</ViewCell>
<ViewCell>
<StackLayout Orientation="Horizontal"
IsVisible="{Binding Source={x:Reference switch}, Path=IsToggled}">
<Label Text="Date To:"/>
<DatePicker Date="{Binding SettingsView.DateTo, Mode=TwoWay}" TextColor="White" FontAttributes="Bold"/>
</StackLayout>
</ViewCell>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Text="Current" Grid.Column="0" x:Name="label" />
<Switch x:Name="switch" IsToggled="{Binding SettingsView.Today, Mode=TwoWay}" Grid.Column="1" />
</Grid>
</ViewCell>
There are many solutions which can implement it .
For example you could use Converter
public class BoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var toggle = (bool)value;
return !toggle;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return true;
}
}
in xaml
<ContentPage.Resources>
<ResourceDictionary>
<local:BoolConverter x:Key="BoolConverter" />
</ResourceDictionary>
</ContentPage.Resources>
IsVisible="{Binding Source={x:Reference switch}, Path=IsToggled, Converter={StaticResource BoolConverter}}"

How could I change a textcoroul or a background colour of a TextCell in a ListView on condition

I wonder, how could I change a colour of textcell in a listview by condition. It doesn't matter if it a background color or a textcolor, I just want to highlight some rows depending on condition. My code example below.
<ListView x:Name="lstData" HasUnevenRows="false" Footer="Footer" ItemSelected="OnSelection" >
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding OrderId}" Detail="{Binding OrderState}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.FooterTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal" Padding="5,5,5,5">
<Button Text="New Order" Clicked="OnNewOrderClicked" />
</StackLayout>
</DataTemplate>
</ListView.FooterTemplate>
</ListView>
public ManageOrder()
{
InitializeComponent();
var vList = App.orderDatabase.GetAllOrders();
lstData.ItemsSource = vList;
for( int i=0; i < vList.Count(); i++ )
{
if( vList[i].IsDispatched == false )
{
// **Change colour of text view**
}
}
}
<ListView x:Name="lstData" HasUnevenRows="false" Footer="Footer" ItemSelected="OnSelection" >
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding OrderId}" Detail="{Binding OrderState}" TextColor= "{Binding StateColor}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.FooterTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal" Padding="5,5,5,5">
<Button Text="New Order" Clicked="OnNewOrderClicked" />
</StackLayout>
</DataTemplate>
</ListView.FooterTemplate>
</ListView>
And in the Order (which is your vlist has) I would have a property with a that is of type Color (the one that is inside xamarin.forms library) which you can control.
Solved it by using Template Selector.
https://developer.xamarin.com/guides/xamarin-forms/templates/data-templates/selector/
You can achieve your requirement by using IValueConverter.
<ContentPage.Resources>
<ResourceDictionary>
<local:Class1 x:Key="class1" />
</ResourceDictionary>
</ContentPage.Resources>
<ListView x:Name="lstData">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding OrderId}" TextColor="{Binding Colors, Converter={StaticResource class1}}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
//Converter class
public class Class1 : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((int)value > 1000)
return Color.Green;
else
return Color.Red;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}

Grouping ListBox with Date

I have no idea how to achieve this, but I have a date and time column in a ListBox. The Date column should not display if the date was already in there. I know that in combination with ListCollectionView and Listview/DataGrids, it is propably possible. But can I achieve this with a ListBox and a List. Keep in mind I am using the MVVM principle. This is my listbox:
<ListBox Grid.Row="2" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding Schedules}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Background="Transparent">
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="{Binding MyDateTime, StringFormat='d' }" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding MyDateTime, StringFormat='t'}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<TextBlock Grid.Column="2" Grid.Row="0" Text="{Binding SomeText}" TextTrimming="WordEllipsis" LineStackingStrategy="MaxHeight" MaxHeight="20" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I have made this in excel to give an example of what I am trying to achieve:
I want the affect where I have highlighted with yellow
Converters
// Order Schedules using System.Linq
public class ToOrderedListConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
List<ScheduleItem> schedules = (List<ScheduleItem>)value;
var subset = from item in schedules
orderby item.MyDateTime.TimeOfDay
orderby item.MyDateTime.ToString("yyyy/MM/dd") descending
select item;
return subset.ToList();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
// Show only first occurrence of date
public class DateToVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
DateTime currentItem = (DateTime)values[0];
List<ScheduleItem> schedules = (List<ScheduleItem>)values[1];
ScheduleItem firstOccurrence =
schedules.Find(item => item.MyDateTime.Year == currentItem.Year
&& item.MyDateTime.Month == currentItem.Month
&& item.MyDateTime.Day == currentItem.Day);
if (firstOccurrence.MyDateTime == currentItem)
return Visibility.Visible;
else return Visibility.Collapsed;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAML
<ListBox Grid.Row="2" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Schedules, Converter={StaticResource ToOrderedListConverter}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Background="Transparent">
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="{Binding MyDateTime, StringFormat='dd/MM/yyyy'}" HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBlock.Visibility>
<MultiBinding Converter="{StaticResource DateToVisibilityConverter}">
<Binding Path="MyDateTime"/>
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ListBox}}"
Path="ItemsSource"/>
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
<TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding MyDateTime, StringFormat='t'}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<TextBlock Grid.Column="2" Grid.Row="0" Text="{Binding SomeText}" TextTrimming="WordEllipsis" LineStackingStrategy="MaxHeight" MaxHeight="20" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You can use this approach for your requirements.
https://code.msdn.microsoft.com/windowsdesktop/CollectionView-Tips-MVVM-d6ebb4a7#content

Xamarin Forms Listview: Deselecting selected item by checking with OnTapped Event

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.

Categories