Label TextColor Binding in DataTamplate xaml Xamarin - xaml

I do have a CollectionView with a binding for the text in the labels. This works without a problem.
But now I want to add a binding for the Text Color and I don't know how to do it.
my xaml:
<CollectionView ItemsSource="{Binding List}" SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<ScrollView>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Text="{Binding AttributFromListObject}" TextColor="{Binding TextColor}" Grid.Row="0" Grid.Column="0"/>
<
</Grid>
</ScrollView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
I have set the bindingcontext in the codebehind.
In a normal label without the DataTemplate, the binding TextColor is working.
How can I tell the xaml that it should use the bindingcontext of the page for the TextColor?
Thanks for your help!

#Json comment had the answer.
Needed to add the following
xmlns:ViewModels="clr-namespace:AppName.ViewModels"
TextColor="{Binding Source={RelativeSource AncestorType={x:Type ViewModels:MyViewModel}}, Path=TextColor}"

Related

Add Grid to ItemTemplate in Xamarin.Forms

In a Xamarin Forms(MAUI) project I would like to add a Grid with some prices inside another Grid placed in a CollectionView
The Grid is like below and I have created a function which returns a Grid. This works fine in an ordinary stacklayout : where I create the grid and add it as a Child of PriceData.
How do i accomplish that in a ItemTemplate of a CollectionView at runtime placing the grid where the placeholder RIGHTHERE I WANT TO ADD A GRID are
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="5" Margin="20,20,20,20" >
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.GotoDetailPage, Source={x:Reference Page}}" CommandParameter="{Binding .}" />
</Grid.GestureRecognizers>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="5*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Aspect="Fill" WidthRequest="60" HeightRequest="60" Source="{Binding .,Converter={StaticResource ImageConverter}}"></Image>
<StackLayout Grid.Column="1" Grid.Row="0">
<Label Text="{Binding Title}" />
<Label Text="{Binding BodyText}" />
<<RIGHTHERE I WANT TO ADD A GRID>>
</StackLayout>
<BoxView Grid.Row="1" Grid.ColumnSpan="2" HeightRequest="1" BackgroundColor="LightGray"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
Sorry if the question was unprecise.
The issue was to manipulate with a Grid placed in a CollectionView.ItemTemplate which was bound to a datasource.
I solved it by creating a ContentView with a StackLayout.
The model was passed as a BindableProperty and
then on propertyChanged I created a Grid and added it as a child of the StackLayout

How to dynamically update ListView height while keeping the ScrollViewer enabled?

ListView is placed inside UserControl which is set in parent XAML to asterix "*" height.
I want to use ListView with possibility to scroll items, when there are items that exceed ListView. It should work for different size of window.
It works fine when I set Grid's RowDefinitions with fixed integer, but when I try to use asterix "*" ScrollViewer disables.
I also tried to bind and update RowDefinition's height via some code behind in overriden MeasureOverride method, but it didn't work as expected.
Here is code inside my UserControl:
<Grid x:Name="ContentArea"
Background="{StaticResource MixerBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="{x:Bind ListViewHeight}" />
</Grid.RowDefinitions>
<ListView
ItemsSource="{x:Bind ViewModel.Source,Mode=TwoWay}"
CanDragItems="True"
CanReorderItems="True"
AllowDrop="True"
SelectionMode="Single"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:Track">
<Grid
Background="LightGray"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
BorderBrush="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<TextBlock
Text="{x:Bind Id}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="24"
Margin="20,5,20,5"/>
<Grid
Background="Black"
Width="500"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Column="1">
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I expect to get the ScrollViewer working correctly, but ListView stay at the old size or scroll bar is disabled - depending on Height value.
Is there any way to achieve dynamically resizing ListView with scroll?
Edit
Here is parent Page XAML code which is loaded into Frame via Light MVVM framework:
<Grid
x:Name="ContentArea">
<Grid
Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
<RowDefinition Height="300" />
</Grid.RowDefinitions>
<maineditor:MainEditorMenuControl x:Name="ProjectMenu" />
<maineditor:MainEditorWorkspaceControl x:Name="Workspace" Grid.Row="1"/>
<maineditor:MainEditorMixerControl x:Name="Mixer" Grid.Row="2" />
</Grid>
</Grid>
Edit 2
I think the problem may be connected with MVVM template I've created with Windows Template Studio plugin for Visual Studio. If I try to recreate minimal solution from scratch with all properties 1:1 as in my app it works in fresh project, but not in mine.
How to dynamically update ListView height while keeping the ScrollViewer enabled?
If you want make RowDefinition height same as the ListView, you could give the ListView a name and use {Binding ElementName=MyListView,Path=ActualHeight}syntax to bind both height property.
<Grid x:Name="ContentArea">
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=MyListView,Path=ActualHeight}" />
</Grid.RowDefinitions>
<ListView
Name="MyListView"
CanDragItems="True"
CanReorderItems="True"
AllowDrop="True"
Loaded="MyListView_Loaded"
SelectionMode="Single"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView.ItemTemplate>
<DataTemplate >
<Grid
Background="LightGray"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
BorderBrush="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<TextBlock
Text="{Binding}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="24"
Margin="20,5,20,5"/>
<Grid
Background="Black"
Width="500"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Column="1">
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>

ListView with grid where padding causes child elements to shrink

I'm currently styling a listview, in which I want to add a separating space between each entity in the ListView. For doing that, I use a Grid for each ViewCell with Margin="0,0,0,10".
I can get my elements to fit inside the grid row, but if I add a padding to the row, to give it some top/bottom spacing, it just scales down the text inside the grid.rowuntil eventually, it disappears.
<ListView Margin="10" HasUnevenRows="false" BackgroundColor="Fuchsia" x:Name="deviceList" ItemsSource="{Binding Devices}" CachingStrategy="RecycleElement" SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid BackgroundColor="Silver" Margin="0,0,0,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="0" VerticalOptions="Center" RowSpacing="10">
<local:IconView Source="BLE.png" Foreground="#3b5998" WidthRequest="30" HeightRequest="30" />
</Grid>
<Grid Grid.Row="0" Grid.Column="1" VerticalOptions="Center">
<Label Text="{Binding Name}" TextColor="Black" />
</Grid>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
How do I add padding to my Grid.Row without scaling down the child elements?

How to set height of row in ListView DataTemplate

Question
How can I increase the height of each row in my DataTemplate. I've set the height multiple times in different elements, however the row height doesn't change from the seemingly default height.
What am I missing?
Xaml
<ListView x:Name="ListViewItems">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Tapped="TapGestureRecognizer_Tapped" Height="400">
<Grid Padding="5" Margin="5" HeightRequest="400">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="400"/>
</Grid.RowDefinitions>
<Label Text="{Binding Title}" Grid.Row="0" Grid.Column="1" FontSize="15"/>
<Image Source="#drawable/cereals.png" Aspect="AspectFill" HeightRequest="400" Grid.Row="0" Grid.Column="0" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Screenshot
If you want to allow a ListView row to set its own height, you need to set the ListView HasUnevenRows property to true.
Just put HasUnevenRows="True"
on the ListView. This should do the trick.

Xamarin Forms: Centering multiple, different controls in a layout?

My XAML looks like this:
<StackLayout Orientation="Vertical" HorizontalOptions="Center">
<controls:BindablePicker HorizontalOptions="Center" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListView Grid.Row="0" Grid.Column="1" HorizontalOptions="Center" SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid BackgroundColor="Aqua">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<controls:BindablePicker Title="Length" Grid.Row="0" Grid.Column="0" BackgroundColor="White" />
<controls:BindablePicker Title="Units" Grid.Row="0" Grid.Column="1" BackgroundColor="White" />
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</StackLayout>
Here's what I'm getting: Attempt
This is pretty much what I want, except I want the content centered within the aqua area so everything is centered horizontally. I don't mind if the left cell is right justified and the right cell is left justified.
Note that I'm wanting to add other content beneath this, like labels and other grids, all centered on the page.
Any help would be greatly appreciated. Thanks.
First of all I do not think that you need a row definition in your inner grid since you have only one row.
Secondly for performance sake,do not user "Auto" , just remove the width property from the column definitions.
By doing this both columns will have the same width... I hope ;)
I think if you made your list view like below then it would fix it, but also try it without HorizontalOptions for the controls.
<ListView Grid.Row="0" Grid.Column="1" HorizontalOptions="Center" SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid BackgroundColor="Aqua">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<controls:BindablePicker Title="Length" Grid.Column="0" BackgroundColor="White" HorizontalOptions = "End" />
<controls:BindablePicker Title="Units" Grid.Column="1" BackgroundColor="White" HorizontalOptions = "Start" />
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Hint: The next release of Xamarin.Forms, which is in the alpha channel now, contains a bindable picker so you do not have to user a 3rd party now.