How To Bind ListView Index - c#

I have a ListView which displays images and index numbers
<ListView x:Name="ImageList" ItemsSource="{x:Bind ViewModel.PictureEntires, Mode=OneWay}">
...
<DataTemplate>
<Grid>
<TextBlock Text="{Binding IndexImageInTheImageListView}" HorizontalAlignment="..."/>
<Image ... HorizontalAlignment="..."/>
</Grid>
</DataTemplate>
This is the challenge:
The ItemSource is from ViewModel.
But the TextBlock needs a Text which comes from different source (e.g. CodeBehind). I need this TextBlock to displays the index of the image in the listview.
Why do I need the index?
Because with this index I want to manipulate the HorizontalAllignment. If the Index is odd number. The index will be displayed on the right side, and the image on the left side.
I know already how to align those elements as long as I get the index number.
For example:
ListView
0 Image: Cat
Image: Dog 1
2 Image: Fish
So far I just know how to print out the index. But I can't bind the item with its index
private void ImageListView_Loaded(object sender, RoutedEventArgs e)
{
foreach (var item in TimelineListView.Items)
{
Debug.WriteLine(TimelineListView.Items.IndexOf(item));
}
}

Related

UWP Grid inside Datatemplate

I have a Pivot where I set the header in my Pivot.HeaderTemplate it is basically just showing Names of Books. In my Pivot.ItemTemplate I want to show a Grid which is build in my .xaml.cs but since the Grid is in my DataTemplate I can not access the Grid x:Name anymore in the code behind in .xaml.cs. books is a Collection of Books which contains a Name and a Title
MainPage.xaml
<Pivot ItemsSource="{x:Bind books}">
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="local:Book">
<TextBlock Text="{x:Bind Name}"/>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate>
<Grid
x:Name="BooksGrid"
BorderBrush="Black" BorderThickness="1 1 0 0"
Margin="0 10 0 0>
</Grid>
</DataTemplate>
</Pivot.ItemTemplate>
Now I want to acces BooksGrid iny the code behind and actually create the Grid
MainPage.xaml.cs
public MainPage()
{
this.InitializeComponent();
}
private void DrawGrid()
{
//create columns of Grid
for (int i = 0; i < booksize.XProperties.Count + 1; i++)
{
BooksGrid.ColumnDefinitions.Add(new ColumnDefinition
{
});
}
BooksGrid.ColumnDefinitions[0].Width = GridLength.Auto;
}
....
Already here at BooksGrid.ColumnDefinitions.Add(...) I get the error that BooksGrid can not be found.
My DrawGrid works if I do not place the Grid definition in my DataTemplate and also outside myPivot. So the MainPage.xaml.csdoes not find it when the Grid is inside my DataTemplate
I've read that the solution might be that I have to acces the Grid instance that I want to work with, as soon as the DataTemplate gets loaded. But I do not know how to do that either.
EDIT PART to first solution:
I'm also using BooksGrid in another method
MainPage.xaml.cs
private void DrawBooksFront(Front front)
{
int row;
int column;
column = booksize.XProperties.IndexOf(front.CustomProps[booksize.XLabel])+1;
row = booksize.YProperties.IndexOf(front.CustomProps[booksize.YLabel])+1;
Frame newFrame = new Frame();
TaskBoardGrid.Children.Add(newFrame);
Grid.SetColumn(newFrame, column);
Grid.SetRow(newFrame, row);
}
The reason you cannot access your BooksGrid is because it will be dynamically generated for each book in the books collection. So for every book a Grid will be generated.
OPTION 1:
You can add a Loaded event to your grid:
<Pivot x:Name="Pivot" ItemsSource="{x:Bind books}">
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="local:Book">
<TextBlock Text="{x:Bind Name}"/>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate>
<Grid
BorderBrush="Black" BorderThickness="1,1,0,0"
Margin="0,10,0,0" Loaded="DrawGrid">
</Grid>
</DataTemplate>
</Pivot.ItemTemplate>
and in your code behind:
private void DrawGrid(object sender, RoutedEventArgs e)
{
Grid grid = sender as Grid;
// Load your grid..
}
EDIT - OPTION 2:
If you'd like to access your grids from code behind in a different way (like suggested in your edit) you can always do the following:
private void DrawBooksFront(Front front)
{
// Loop through the pivot's items and get the content from each item's ContentTemplate.
foreach (var item in Pivot.Items)
{
PivotItem pivotItem = Pivot.ContainerFromItem(item) as PivotItem;
Grid grid = pivotItem.ContentTemplate.LoadContent() as Grid;
// Do something with the grid.
}
}
If your goal is to display previews of the pages of the book inside a PivotItem in a grid-like manner [picture below], then you're better off placing GridView in a DataTemplate of Pivot.ItemTemplate and using data binding to display those pages automatically, this would eliminate the need to write the code in xaml.cs that you showed.
Please, share more details about your app (what you're given and what the end result should look like) so we could help you better.

Block user navigation in a Pivot item for UWP apps

How can you block a user from clicking on a Pivot item in a UWP XAML app but still show the heading for each pivot item? For example, I have three pivot items that are labeled "Step 1", "Step 2", and "Step 3". I want each of those items to show up at the top of the pivot table, but not be user engagable. They are only there to proivde awarness to the users current location in a process.
I have tried IsLocked="true" in the definition of the pivot table, but it only shows me the title for the pivot item I am currently on.
I tried IsEnabled="false" and that didn't work. Then I tried data binding to a property and used the setter to restrict its value, and that did work.
View:
<Pivot SelectedIndex="{x:Bind PageViewModel.MyPivotIndex, Mode=TwoWay}">
<PivotItem Header="Item1">
<TextBlock Text="Stuff1"/>
</PivotItem>
<PivotItem Header="Item2" IsEnabled="False">
<TextBlock Text="Stuff2"/>
</PivotItem>
</Pivot>
ViewModel:
private int _myPivotIndex;
public int MyPivotIndex
{
get
{
return _myPivotIndex;
}
set
{
if (ConditionMet)
{
_myPivotIndex = value;
}
else
{
_myPivotIndex = 0;
OnPropertyChanged("MyPivotIndex");
}
}
}
A non-MVVM option that should work is if you used the "SelectionChanged" event in the code-behind to check a condition and then if need be set it back to Item1 by setting SelectedItem or SelectedIndex.
If you want the "disabled" items to not highlight on mouse-over, you'll have to copy the style (https://msdn.microsoft.com/en-us/library/windows/apps/mt299144.aspx) and modify it in the the "PointerOver" Visual State.

Accessing ListBox and other children in a LongListSelector

I'm building an app where there's a arbitrarily long list of items where you can click on any of them and edit in place. As you edit any of these items I want to programmatically change focus to the next item in the list.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<phone:LongListSelector x:Name="MainLongListSelector" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainLongListSelector_SelectionChanged">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,-10,0,-12">
<TextBox x:Name ="tb" Text="{Binding TheText}" TextWrapping="Wrap" TextChanged="TextBox_TextChanged" />
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
As the user types in the first TextBox and his text exceeds a certain # of characters (e.g. 138) I want to either add another item to the list as the next item and change focus to it, or, if there's already a next item, change focus to it.
I can't figure out how to get access to
1) The root list box
2) The TextBox control within an item given a list box item ID
Here's what I tried. When this runs, the MainLongListSelector.SelectedITem = nextItem causes the next item to be selected, but it does NOT get focus.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
var editBox = sender as TextBox;
var selectedItem = MainLongListSelector.SelectedItem as ItemViewModel;
if (editBox != null && selectedItem != null && editBox.Text.Length > 138) {
// Move data at end to next box
var overflow = editBox.Text.Substring(138, editBox.Text.Length - 138) ;
selectedItem.Tweet = editBox.Text.Substring(0, 138);
var nextItem = App.ViewModel.Items[int.Parse(selectedItem.ID) + 1];
nextItem.Tweet = overflow;
MainLongListSelector.SelectedItem = nextItem;
}
}
I want to be able to access the actual TextBox of that nextItem so I can explicitly set focus to it.
The same question applies if I just use ListBox but the issues are different. In the ListBox case when the DataTemplate contains a TextBox and focus is set, I don't get SelectionChanged events...which is why I'm sticking with LongListSelector.
If I understand you correctly, you want to the TextBox get focus when the item item selected.
If this is what you need, here is a way to bind LisBoxItem.IsSelected To Element.Focus():
http://social.msdn.microsoft.com/Forums/en-US/adeb3e7f-16df-4c7b-b2d2-d7cdedb32ac0/setting-focus-of-a-textbox-inside-a-listbox?forum=wpf

Creating Image control dynamically inside a listbox based on number of items user wants using C#

Simple question but I am totally confused. I am developing a wp7 app using C#. I want a listbox with input number of image item which source should be same i.e. the list box should contain 'n' Image control with source set to a single image where 'n' is number of Listbox Item enter by user. e.g. If the user input '10', then the listbox should have ten items. I want the listbox ItemsPanelTemplate as Wrap-panel. Can somebody suggest me how to get this?
Define a ListBox in your XAML something like this
<ListBox x:Name="ListBoxImages">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Imagesource}" Width="300"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and then set its Source in the code behind like this
int noOfImages = 10; //Take the input from user
List<ImageClass> imageList = new List<ImageClass>();
for(int i=0; i<noOfImages; i++)
imageList.Add(new ImageClass() { Imagesource = "/user.jpg" });
ListBoxImages.ItemsSource = imageList; //Set the source of the listbox here
where ImageClass is,
public class ImageClass
{
public String Imagesource { get; set; }
}
The above is a sample for your understanding. Please customize wisely to suit your needs

Dynamically bind a textblock in a looping selector in wp7

I am developing an application where I have a class called UIManager in which there is a method which has an array of data
public void DisplayCatalog(string[] displayName, BitmapImage[] icons)
{
DisplayItem.Clear();
for (int i = 0; i < displayName.Length; i++)
{
DisplayItem.Add(new ItemList { WidgetName = displayName[i], Icon = icons[i] });
}
NotifyPropertyChanged("UI");
}
Now I want this data ie;WidgetName to be displayed in my MainPage where I have used a Looping selector.
*<custom:LoopingSelector x:Name="selectorLeft" ItemMargin="5" ItemSize="145,145" Margin="6,0,-6,22">
<custom:LoopingSelector.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding WidgetName}"/>
</StackPanel>
</DataTemplate>
</custom:LoopingSelector.ItemTemplate>
</custom:LoopingSelector>
*
Also I need to scroll the looping selector Horizontally.
How can I achieve this...??? Any valuable solutions Please.......
I have used Horizontal Looping Selector but I am not getting how to bind the data from my UIManager class on to the Horizontal Looping Selector..
<toolkit:HorizontalLoopingSelector Grid.Row="0" Margin="12" Height="128" ItemSize="128,128" ItemTemplate="{StaticResource ?????}">
<toolkit:HorizontalLoopingSelector.DataSource>
????????
</toolkit:HorizontalLoopingSelector.DataSource>
</toolkit:HorizontalLoopingSelector>
u need to create a datasource class and bind the values to the looping selector source .its similar to binding source to the vertical looping selector.
Visit http://www.windowsphonegeek.com/articles/WP7-LoopingSelector-in-depth--Part1-Visual-structure-and-API
Check out this resource if you still require a horizontal loop selector:
http://blog.supaywasi.com/2011/06/horizontal-looping-selector/

Categories

Resources