Xamarin: Scrolling to a position of a ListView when the listview is contained inside of a CarouselViewControl - android-layout

Is there any way to directly access a listview that is contained within a CarouselViewControl?
I have a Carousel for the left and right swiping and inside each page, there is a listview. However, since the ListView is contained within the CarouselViewControl, I can't access it directly via code to call the ScrollTo() function nor is the ScrollTo function bindable. I've also tried looping through all of the rendered controls via a FindVisualChildren extension and it appears that when the Carousel renders, it doesn't render the listview as a listview so I don't see any way that I can scroll to a specific vertical position within it.
I'm trying to make an alphabet selector (similar to the one on android's music player) so that when the user clicks a letter, it takes them to that position in the listview. However, it also has to be inside of a carousel view so that it shows a different list when they swipe between the other pages.
Anyone have any ideas if there's any [other] way to do this?
<controls:CarouselViewControl x:Name="RecipeList" Orientation="Horizontal" InterPageSpacing="10" ItemsSource="{Binding ProductList}"
VerticalOptions="FillAndExpand" PositionSelected="RecipeList_PositionSelected"
HorizontalOptions="FillAndExpand" BackgroundColor="Transparent">
<controls:CarouselViewControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<ListView x:Name="sublist" Margin="5,10,-10,-10" ItemSelected="RecipeList_ItemSelected" IsGroupingEnabled="True"
GroupDisplayBinding="{Binding Key}" ItemsSource="{Binding ProductsList}" VerticalScrollBarVisibility="Never"
SeparatorVisibility="None" HasUnevenRows="True" BackgroundColor="Transparent" SelectedItem="{Binding ScrolledItem}">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell Height="1">
<Label Text="" />
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" MinimumHeightRequest="{StaticResource ImageSize}"
Padding="15,10,0,0">
<Frame HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Padding="0" Margin="0,5,10,0" CornerRadius="10"
BackgroundColor="#FCFAF8" BorderColor="#F37623" HasShadow="True">
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding Image}" Grid.Column="0" Grid.Row="0" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand" Aspect="AspectFit"/>
<Grid Grid.Row="0" Grid.Column="1" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Text="{Binding ProductNane}" Grid.Row="0" Grid.Column="0" HorizontalOptions="StartAndExpand" VerticalOptions="StartAndExpand" FontAttributes="Bold" FontSize="Medium" TextColor="Black" BackgroundColor="Transparent" Margin="0,5,0,0"/>
<Image Source="{Binding HeartImage}" Grid.Row="0" Grid.Column="1" HorizontalOptions="End" VerticalOptions="StartAndExpand" BackgroundColor="Transparent" HeightRequest="30" WidthRequest="30" Aspect="AspectFit" Margin="0,5,10,1" >
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="HreatImageClicked"/>
</Image.GestureRecognizers>
</Image>
<Label Text="{Binding Description}" Grid.Row="1" Grid.Column="0" Style="{StaticResource StandardLabel}" FontSize="Small" MaxLines="2" LineBreakMode="TailTruncation" />
<lv:RatingImage Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" ImageDeselect="star_line.png" ImageSelect="yellow_star.png" ImageHeight="12" ImageWidth="12"
ItemsNumber="5" InitialValue="{Binding Rating}" HorizontalOptions="End" VerticalOptions="End"
SpaceBetween="2" IsReadOnly="True" Margin="0,0,2,0" />
</Grid>
</Grid>
</Frame>
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="RecipeDetailPage" />
</Grid.GestureRecognizers>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</controls:CarouselViewControl.ItemTemplate>
</controls:CarouselViewControl>
Thanks!

I can't access it directly via code to call the ScrollTo() function nor is the ScrollTo function bindable.
You want to get ListView from CarouselViewControl DataTemplate, I think it is unreasonable, because it is just DataTemplate, I don't find any way to access control in DataTemplate.
So I suggest you can Create an ExtendedScrollView and expose the ScrollTo method into a read only bindable ICommand property. Bind it to your view model corresponding command and use it from there.
You can reuse the control everywhere and it can support any kind of scrolling scenario. You need to create an object to be used a the command parameter that will embed the parameters of ScrollTo, and use it inside the bindable ICommand inside ExtendedScrollView.

Related

Xamarin Left margin in iPad

I face strange behavior when I am populate list view all cells have left margin
tested Device iPad 9 in simulator , iPad 12 in simulator
here is screen of my issue
and my second list
here is my Xaml
<customRender:ExtList x:Name="listViewFlights" BackgroundColor ="{StaticResource white_color}"
ItemTapped="ListView_OnItemTapped" SeparatorColor="Gray" SeparatorVisibility="Default"
MinimumHeightRequest="40" IsPullToRefreshEnabled="True" Refreshing="ListViewFlights_Refreshing" >
<ListView.ItemTemplate>
<DataTemplate>
<customRender:CustomViewCell >
<StackLayout Spacing="0" BackgroundColor="Aqua">
<Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" x:Name="gridCell" RowSpacing="0" ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3.25*"></ColumnDefinition>
<ColumnDefinition Width="4*"></ColumnDefinition>
<ColumnDefinition Width="4.75*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="{Binding FirstListColumn}" Style="{StaticResource GridItemStyleLabelStart_os}" Margin="10,0,0,0"/>
<StackLayout Grid.Row="0" Grid.Column="1" Padding="{Binding FlightListColumn2Padding}" VerticalOptions="Center" >
<Label Text="{Binding Dep_Dest}" Style="{StaticResource GridItemStyleLabel_os}" HorizontalTextAlignment="Start"></Label>
</StackLayout>
<Grid Grid.Row="0" Grid.Column="2" HorizontalOptions="FillAndExpand" RowSpacing="0" >
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1.5*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition Width="5.5*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Frame Grid.Row="0" Grid.Column="0" IsVisible="{Binding IsRecalculated}" Padding="0" Margin="0,7" OutlineColor="#5C768E" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" HasShadow="False" BackgroundColor="Transparent">
<Label Text="R" Style="{StaticResource GridItemStyleLabelStart}" HorizontalOptions="CenterAndExpand" IsVisible ="{Binding IsRecalculated}" />
</Frame>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding ATCCtot }" Style="{StaticResource GridItemStyleLabelStart}" TextColor="Red" HorizontalOptions="Start" />
<Label Grid.Row="0" Grid.Column="2" Text="{Binding PreparedStd}" Style="{StaticResource GridItemStyleLabelEnd_os}" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End" />
</Grid>
<BoxView x:Name="SelectedBox" Grid.Row="0" Grid.Column="3" Opacity="{Binding IsSelected}" BackgroundColor="{StaticResource sub_header}" >
<BoxView.WidthRequest>
<OnIdiom x:TypeArguments="x:Double" Tablet="5" />
</BoxView.WidthRequest>
</BoxView>
</Grid>
</StackLayout>
</customRender:CustomViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</customRender:ExtList>
my tries to fix the issue :
after long search I find soluation in xamarin site , is to make custom render to my list view but it docent work
public class CustomListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged (e);
if (e.NewElement != null) {
var listView = Control as UITableView;
listView.CellLayoutMarginsFollowReadableWidth = false;
}
}
}
reference https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/viewcell/
This is a known bug that is in the process of being fixed.

UWP Accessing content in a data bound ListView

I have a ListView with a ListView.ItemTemplate if it is important: the ListView is part of a Grid). I will strip it down here for the minumum:
<ListView x:Name="lstFotos" Grid.Row="2" Grid.Column="1" Height="auto" Tapped="imageControl_Tapped" >
<ListView.ItemTemplate>
<DataTemplate>
<Grid IsTapEnabled="True" >
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image x:Name="imageControl" Width="200" Height="200" Source="{Binding DateiSoftwareBitmapSource}" IsTapEnabled="True" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" />
<TextBlock x:Name="txtImageDateDescription" Text="Aufnahmedatum: " Grid.Column="1" Grid.Row="0" />
<TextBlock x:Name="txtImageDescriptionDescription" Text="Beschreibung: " Grid.Column="1" Grid.Row="1" />
<TextBlock x:Name="txtImageDate" Text="{Binding Datum}" Grid.Column="2" Grid.Row="0" />
<TextBox x:Name="txtImageDescription" Text="{Binding Beschreibung}" Grid.Column="2" Grid.Row="1" />
<Button x:Name="btnSpeichern" Content="Speichern" Grid.Column="3" Grid.Row="1" Click="btnSpeichern_Click" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In the code behing I do a
lstFotos.ItemsSource = AlleAnzeigeFotos
AlleAnzeigeFotos is a List(Of myClass), myClass contains the properties Datum, Beschreibung, DateiSoftwareBitmapSource.
What I want to do is that the user can edit the textfield, presses on the button and in the code behing I want to update the class and do some more stuff.
How can I get the appropriate instance of that class when I click the button?
UPDATE:
This is how it looks like:
"Beschreibung" (english: description) is empy after adding a foto and should be editable and stored by clicking "Speichern" (save).
(sender as Button).DataContext will give you the item which you clicked. Cast it to appropriate type of your class
update
Text="{Binding Beschreibung,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
var userenteredstring=((sender as Button).DataContext as your class).Beschreibung

UWP - PointerExited is not fired when Grid is in Listview

I want to show a image in the listview, and the pointer is over the image, I will display the filesize/filename and a download button at the bottom of the image. And I also can open the file by tap the image.
I registered the PointerEntered and PointerExited event of the control, and tried to show or hide the filesize/filename/download button when the events get fired.
When the finger touch the image, the PointerEntered is fired. However, on touch screen(Phone, tablet), when the finger left the image, the PointerExited event is not fired. When I operate with mouse on tablet, everything is working correctly.
Here is my code snippet:
<Grid>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="PointerEntered" >
<Core:InvokeCommandAction Command="{Binding ShowFileInfoCommand}"></Core:InvokeCommandAction>
</Core:EventTriggerBehavior>
<Core:EventTriggerBehavior EventName="PointerExited" >
<Core:InvokeCommandAction Command="{Binding HideFileInfoCommand}"></Core:InvokeCommandAction>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<Image Source="{Binding ThumbnailUri}" Stretch="{Binding ImageStretch}" MaxHeight="200" MaxWidth="350" Height="{Binding FileHeight}" HorizontalAlignment="Right">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Tapped" >
<Core:InvokeCommandAction Command="{Binding ConversationRoom.OpenFileFlipViewCommand,Source={StaticResource Locator}}" CommandParameter="{Binding}"/>
</Core:EventTriggerBehavior>
<Core:EventTriggerBehavior EventName="RightTapped">
<Core:InvokeCommandAction Command="{Binding RightTappedMessageCommand}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Image>
<Grid Background="White" Opacity="0.75" Height="50" x:Name="InfoGrid" VerticalAlignment="Bottom" Visibility="{Binding NeedShowFileInfo, Converter={StaticResource BoolToVisible}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Margin="6,0,0,6" Text="{Binding FileName}"/>
<TextBlock Grid.Row="1" Margin="6,0,0,6" Text="{Binding FileSize}"/>
<FontIcon Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,6,6" Glyph="" FontFamily="../Assets/fontello.ttf#fontello">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Tapped">
<Core:InvokeCommandAction Command="{Binding DownloadCommand}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</FontIcon>
</Grid>
</Grid>
And if I move the Grid out of the listview, but in a stackpanel/Grid, everything goes fine.
Can anyone help on this issue?
Thank you!

Align radio button to right side of popup

I have a popup for select colors.
<Popup x:Name="colorSelectorPopup">
<Border BorderThickness="1" BorderBrush="Gray">
<StackPanel HorizontalAlignment="Stretch">
<Grid x:Name="colorSelectorTitle" Height="40" VerticalAlignment="Top">
<TextBlock x:Name="popupTitle" TextTrimming="CharacterEllipsis" FontSize="16" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="8"/>
</Grid>
<ListView x:Name="colorList" HorizontalAlignment="Stretch" Background="White">
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="tbColor" Text="{Binding ColorName}" Foreground="{Binding ForegroundColor}" HorizontalAlignment="Left"/>
<RadioButton Grid.Column="1" x:Name="radioColor" GroupName="colorRadio" Tag="{Binding SelectionColor}" MinWidth="32" Checked="radioColor_Checked"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Border>
</Popup>
I want the radio button to show on the right side. But It looks as in the image.
How can I move the radio button to the right side?
I got the answer from here.
By Adding the following xaml I got the desired output.
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
This works for me. I have updated my xaml as follows
<Popup x:Name="colorSelectorPopup">
<Border BorderThickness="1" BorderBrush="Gray">
<StackPanel HorizontalAlignment="Stretch">
<Grid x:Name="colorSelectorTitle" Height="40" VerticalAlignment="Top">
<TextBlock x:Name="popupTitle" TextTrimming="CharacterEllipsis" FontSize="16" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="8"/>
</Grid>
<ListView x:Name="colorList" HorizontalAlignment="Stretch" Background="White">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="tbColor" Text="{Binding ColorName}" Foreground="{Binding ForegroundColor}" HorizontalAlignment="Left"/>
<RadioButton Grid.Column="1" x:Name="radioColor" GroupName="colorRadio" Tag="{Binding SelectionColor}" MinWidth="32" Checked="radioColor_Checked"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Border>
</Popup>
Since the grid only contains 2 columns and the 2nd column only contains the radio button I would set the column definition to a fixed with for the 2nd one instead of auto. see if that works.
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>

Setting column width to 50% of available width in windows phone 8.1

Developing/learning about WP8.1 for the 1st time.
This question is about layout.
I have 2 buttons.
I want them at the bottom of my screen.
I want each button to take 50% of the available width of the screen.
Similar to this:
So far I have this:
And this is my markup:
<Page
x:Class="Informed.BasicPage1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Informed"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
>
<Grid x:Name="LayoutRoot">
<Grid.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="45"/>
</Grid.RowDefinitions>
<!-- Title Panel -->
<StackPanel Grid.Row="0" Margin="19,0,0,0" Grid.ColumnSpan="2">
<Image Name="imgHeader" Grid.Row="0" Source="Images/bannershort.jpg" Stretch="UniformToFill"/>
<TextBlock Text="Log In" Margin="0,-6.5,0,26.5" Style="{ThemeResource HeaderTextBlockStyle}" CharacterSpacing="{ThemeResource PivotHeaderItemCharacterSpacing}"/>
</StackPanel>
<StackPanel Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.ColumnSpan="2">
<TextBox Name="email" Header="Email address"/>
<PasswordBox Name="password" Header="Password"/>
<CheckBox Name="showPassword" Content="Show password"/>
<!-- Content body -->
<TextBlock Name="body" Style="{StaticResource MessageDialogContentStyle}" TextWrapping="Wrap">
<TextBlock.Text>
Enter Email Address and Password created.
</TextBlock.Text>
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="2" Grid.Column="0" Margin="0,0,0,0" Grid.ColumnSpan="1">
<Button Content="hello" Grid.Column="0" FontFamily="Global User Interface" />
</StackPanel>
<StackPanel Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="1">
<Button Content="hello2" Grid.Column="1" FontFamily="Global User Interface" />
</StackPanel>
</Grid>
</Page>
Remove those StackPanels they are not needed. When you want something to take available space use HorizontalAlignment = Stretch:
<Button Content="hello" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Stretch" FontFamily="Global User Interface" />
<Button Content="hello2" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Stretch" FontFamily="Global User Interface" />
You will also need to make your columns equal width:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
You may also think of adding Margin="20,0,10,0" (first) and Margin="10,0,20,0" (second).
There is no point in putting one control inside panel (except some rare cases). You may also modify your code and put those Buttons inside a Grid then there is no need to make the whole main Grid with two columns:
<Grid Grid.Row="2" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Content="hello" Grid.Column="0" HorizontalAlignment="Stretch" FontFamily="Global User Interface" />
<Button Content="hello2" Grid.Column="1" HorizontalAlignment="Stretch" FontFamily="Global User Interface" />
</Grid>

Resources