Data bind the index of an item in a listbox? - windows-phone-7

I have a set of local high scores (ObservableCollection) and they're data bound to a ListBox so I can display them. Here's what I currently have, the "{Binding Index}" of the first TextBlock is where I'm trying to grab the index of the current item but I'm not entirely sure if it's possible through data binding:
<ListBox Grid.Row="1" x:Name="localScoresListBox" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Index}" Grid.Column="0" />
<TextBlock Text="{Binding PlayerName}" Grid.Column="1" />
<TextBlock Text="{Binding Score}" Grid.Column="2" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So my question. Using data binding, can you grab the index of the current item?
If it is possible I believe it would be 0-based and since I want the first rank to be 1 instead of 0, could you do something like {Binding Index+1}?
EDIT: There's a similar question here for WPF and there didn't seem to be a way to do it then either: WPF ListBox bind to index of the item

Not that I know of - especially since the item that you are binding will be of whatever type your object is, and it probably doesn't have an Index property.
I'd suggest adding the index property to your data objects (it can be added / manipulated when you populate the collection).

Related

How to set all the item template data into a single view in Xamarin Carousel

I have tried to make all the items in the itemtemplate into a single view as like in the below image, how to achieve this by using Xamarin CarouselView, i am using like this
carousel = new CarouselView();
carousel.BindingContext = this;
carousel.ItemTemplate = itemTemplate;
carousel.SetBinding(CarouselView.ItemsSourceProperty, new Binding(nameof(this.Items), mode: BindingMode.OneWay));
LinearItemsLayout linearItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal);
linearItemsLayout.SnapPointsAlignment = SnapPointsAlignment.Start;
linearItemsLayout.SnapPointsType = SnapPointsType.Mandatory;
carousel.ItemsLayout = linearItemsLayout;
this.Children.Add(carousel,0,1);
Expected UI
The easiest way of doing something like that would be to use the Horizontal CollectionView
CollectionView can display its items in a horizontal list by setting its ItemsLayout property to HorizontalList:
When you check the documents it gives a similar example
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
LineBreakMode="TailTruncation" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
LineBreakMode="TailTruncation"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
Alternatively, this layout can also be accomplished by setting the ItemsLayout property to a LinearItemsLayout object, specifying the Horizontal ItemsLayoutOrientation enumeration member as the Orientation property value:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
...
</CollectionView>
This results in a single row list, which grows horizontally as new items are added:

How can I use the Design Tab in Visual Studio when designing XAML UI for a UWP App that uses Data Template in List View?

This is a bit of a tricky question to put succinctly but here goes. Snippets have been included to get the point across.
This problem came about whilst trying to solve another problem, to which a solution was found on SO, but which required to right-click and edit the default style of a TextBox, which I can't do because the TextBox in question is part of a DataTemplate on a databound ListView which of course has no content at design time.
Here are some snippets: I use a data template to control the content/layout of my listview like so:
<ListView x:Name="DataItemList"
ItemsSource="{x:Bind MasterMenuItem.DataObjects, Mode=OneWay}"
SelectedItem="{x:Bind SelectedItem, Mode=TwoWay}"
SelectionMode="Single"
ItemTemplate="{StaticResource DataListItemTemplate}">
</ListView>
and a data template as a page/control resource
<DataTemplate x:Key="DataListItemTemplate" x:DataType="vm:DataObjectListItem">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<Grid Height="40" Margin="10 0 0 0">
<Grid.Resources>
<SolidColorBrush x:Key="brush" Color="Silver"/>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" MinWidth="240" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderBrush="{StaticResource brush}" BorderThickness="1 1 1 1">
<FontIcon Name="Icon"
Grid.Column="0"
VerticalAlignment="Center"
FontSize="32"
Glyph="{x:Bind ListItemIcon}" />
</Border>
<Border Grid.Column="1" BorderBrush="{StaticResource brush}" BorderThickness="1 1 1 1">
<TextBlock Name="Data Object Name"
Padding="6 4 6 4"
Text="{x:Bind Name, Mode=OneWay}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontWeight="Bold"
TextWrapping="WrapWholeWords"/>
</Border>
</StackPanel>
</DataTemplate>
When I view my page in the Design tab of visual studio (instead of the XAML tab) I see nothing useful, unlike if, for example, I put a TextBlock in my XAML with Text="Hello" I would be able to see 'Hello' in the Design tab and crucially Right-Click on it to do certain things...
Is there a way to 'populate' the list with some dummy data, or the text box with some dummy text in order to visualize the runtime layout in the Design tab?

Xamarin.Forms: how to set Images to get the expected result

I'm looking for a good way to implement a control that looks like a ListView with 2 columns, where each column has distinct height. As I didn't found another solution, I've decided to do it through a Repeater control.
The expected result is something like this:
All the items come from the same DataSource, and this DataSource will contain between one and a dozen of items.
The items must be splitted automatically (by modulo) into the 2 columns
When the user click on the button related to the item, this will open the item's detail page
The red squares are images that must have the same height/width
I'm working on the design of the cell DataTemplate, but I didn't see how to manage the images:
The distinction between the 2 columns is given by a Grid containing 2 Columns
Then I specify the DataTemplate for each column
<ScrollView>
<Grid Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Col.1 -->
<tabletControls:Repeater Grid.Column="0" Margin="10"
ItemsSource="{Binding ListProductItems}">
<tabletControls:Repeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" >
<StackLayout>
<ffimageloading:CachedImage Source="{Binding Icon}"
Aspect="AspectFill"/>
</StackLayout>
...
</StackLayout>
</ViewCell>
</DataTemplate>
</tabletControls:Repeater.ItemTemplate>
</tabletControls:Repeater>
<!-- Col.2 -->
<tabletControls:Repeater Grid.Column="1" Margin="10"
ItemsSource="{Binding ListProductItems}">
<tabletControls:Repeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" >
<StackLayout>
<ffimageloading:CachedImage Source="{Binding Icon}"
Aspect="AspectFill"/>
</StackLayout>
...
</StackLayout>
</ViewCell>
</DataTemplate>
</tabletControls:Repeater.ItemTemplate>
</tabletControls:Repeater>
</Grid>
</ScrollView
But this doesn't work as expected, as the image's height/width are not the same:
I already tried to play with Aspect (AspectFill, AspectFit, Fill) or VerticalOptions/HorizontalOptions, withou any result...
Is it possible to achieve the expected result without specify an HeightRequest? Are there other options?

How to set the toogle switch control on/off dynamically by binding it for window phone 8.1 RT?

Actually I have taken the toogleswitch in the List box and it is generated dynamically.
And I am binding the database fields values to the list box.
and there is a field "Selected" which has values 0/1.
So I want the switch to be On/Off based on that value.
Also tell me How would I get the particular List Item on the toogleswitch change. because I want to change the Database field( Name of field is "Selected") for the particular row in the list box
cs Code
___________
List<Audit_Group> groupSectionList = e.Parameter as List<Audit_Group>;
lbGroupSection.ItemsSource = groupSectionList; // lbGroupSection is the ListBox
.xaml code
_________________
<ListBox x:Name="lbGroupSection" Foreground="Black" Margin="6" HorizontalAlignment="Left" VerticalAlignment="Center" BorderThickness="1" Width="auto">
<ListBox.ItemTemplate>
<DataTemplate>
<!--<Border BorderBrush="Black" BorderThickness="1">-->
<!--ONE ROW-->
<StackPanel VerticalAlignment="Center">
<Grid Background="WhiteSmoke">
<TextBlock Foreground="Black" Margin="5,0,0,0" x:Name="tbSectionName" TextWrapping="Wrap" Text="{Binding Section_Name}" FontSize="20"/>
</Grid>
<Border BorderBrush="Black" BorderThickness="1">
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="270"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Left" Foreground="Black" Margin="5,0,0,0" x:Name="tbGroupName" Text="{Binding Group_Name}" FontSize="20"/>
<ToggleSwitch x:Name="tsGroup" Foreground="WhiteSmoke" Grid.Column="1" Toggled="tsGroup_Toggled" Style="{StaticResource ToggleSwitchButtonStyle1}" /> /* How to make it On/Off based on the DB field value */
</Grid>
</Border>
</StackPanel>
<!--END ONE ROW-->
<!--</Border>-->
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Have a converter that returns bool depending upon your dynamic value(return true for 1 and false for 0) bind the value to the selected property of the toggle button via the converter. That should solve it.

Slow Page loading when using ExpanderView & Binding (Windows Phone 7)

I have a Panorama control, which has an ExpanderView Item (from Silverlight toolkit).
My client wants this page to be customizable. Thats why I created 3 level of binding:
The PanoramaItems, the ExpanderView headers and the ExpanderView content.
The problem when I set the itemssource of the Panorama control. it takes about 5 seconds to show the items.
Any idea how I can solve this?
C# code:
private void panorama_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = App.Products;
}
XAML Code:
<controls:Panorama Loaded="panorama_Loaded" x:Name="panorama" ItemsSource="{Binding}">
<controls:Panorama.ItemTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding Sub_Products}" >
<ListBox.ItemTemplate>
<DataTemplate>
<toolkit:ExpanderView Header="{Binding}" Expander="{Binding}" ItemsSource="{Binding Sub_Sub_Products}">
<toolkit:ExpanderView.ExpanderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image VerticalAlignment="Center" Source="Images/List.png" Width="25" />
<TextBlock Text="{Binding Title}" />
</StackPanel>
</DataTemplate>
</toolkit:ExpanderView.ExpanderTemplate>
<toolkit:ExpanderView.ItemTemplate>
<DataTemplate>
<Grid Margin="-30,0,0,0" Background="White" Width="450" Tap="Grid_Tap" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="{Binding ImageSource}" />
<StackPanel VerticalAlignment="Top" Grid.Column="1">
<TextBlock Text="{Binding Title}" />
<TextBlock Text="{Binding Description}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
<TextBlock Margin="0,12,32,0" Grid.Row="1" Text="Learn more" />
</StackPanel>
</Grid>
</DataTemplate>
</toolkit:ExpanderView.ItemTemplate>
</toolkit:ExpanderView>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</controls:Panorama.ItemTemplate>
</controls:Panorama>
You could try to collapse the panorama items that are off screen and only set visibility to visible on demand. That should at least reduce the size of the visible tree.
A good way to find the slow parts is to use the profiler in Visual Studio. You will find one frame which is really slow (it will have a render time of 5 seconds in your case). Then dig into the visual tree of that frame and see which elements took a long time to render and try to optimize these.
Remove the ExpanderView ItemsSource binding in xaml and bind to it when the Expander is manupulated in code. Just leave it as ItemsSource="{Binding}". That way you will dynamically build you visual tree as the user taps on the expander.
The event handler is something like below. I am assuming Product is the type in your App.Products list. Also ensure that you hook up the event in your xaml for the expander.
private void ExpanderView_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
var expander = sender as ExpanderView;
expander.ItemsSource = (expander.DataContext as Product).Sub_Sub_Products;
}
Hope this solves your slow loading issues and is not too late at this time.

Resources