WP8 ListPicker Bind - c#

When I bind my data via item source to my ListPicker:
C#:
var sightingTypes = SightingTypes.List;
sightingTypesPicker.ItemsSource = sightingTypes;
XML:
<toolkit:ListPicker x:Name="sightingTypesPicker" ItemsSource="{Binding sightingTypes, ElementName=this}">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" FontSize="{StaticResource PhoneFontSizeSmall}"/>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
</toolkit:ListPicker>
I can see the Name being shown in the ListPicker, but, when I click on the ListPicker it shows the List of the Object Type, like this:
MyProject.Model.SightingType
MyProject.Model.SightingType
MyProject.Model.SightingType
MyProject.Model.SightingType
MyProject.Model.SightingType
MyProject.Model.SightingType
How do I:
A: Make the Name Property show when the list shows
B: Bind the ID Property as the Value but not show it

You need to assign FullModeItemTemplate for that to work:
<toolkit:ListPicker x:Name="sightingTypesPicker" ItemsSource="{Binding sightingTypes, ElementName=this}">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" FontSize="{StaticResource PhoneFontSizeSmall}"/>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" FontSize="{StaticResource PhoneFontSizeSmall}"/>
<TextBlock Text="{Binding SomeOtherProp}" FontSize="{StaticResource PhoneFontSizeSmall}"/>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
EDIT: To answer your question B: You can use the SelectedItem DependencyProperty to get the instance of the selected object:
With MVVM approach:
<toolkit:ListPicker x:Name="sightingTypesPicker"
ItemsSource="{Binding SightingTypes}"
SelectedItem="{Binding SelectedSigntingType, Mode=TwoWay}">
With code-behind approach:
sightingTypesPicker.SelectionChanged += (s, e) => {
MessageBox.Show(((SightingType)e.AddedItems[0]).ID);
};

Related

How do I refer to a control in a WPF nested ListView?

My XAML:
<ListView x:Name="lvAlbums" ItemsSource="{Binding XPath=/downloads/Album}" SelectionMode="Multiple">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="spAlbum">
<!-- Displays first level attributes -->
<TextBlock x:Name="AlbumName" Text="{Binding XPath=#Name}"/>
<TextBlock x:Name="AlbumArtist" Text="{Binding XPath=#Artist}"/>
<ListView x:Name="lvTracks" ItemsSource="{Binding XPath=Item}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="spTrack">
<!-- Displays the second level attributes -->
<TextBlock x:Name="trackName" Text="{Binding XPath=#Name}"/>
<ProgressBar x:Name="pb1" Minimum="0" Maximum="100" Height="5px" Margin="0,0,0,0"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
It populates just fine from an xml file. I have an album and listed underneath are the tracks and a progress bar for each track.
I am now looping though the XML to download each track. How do I refer to the progressbar?
(ProgressBar)lvAlbums[curAlbum].lvTracks[curTrack].spTrack["pb1"]
Something like that.
Please see if this works for you :
var innerListView = lvAlbums.ItemTemplate.FindName("lvTracks", lvAlbums) as ListView;
ProgressBar pbar = innerListView.ItemTemplate.FindName("pb1", innerListView ) as ProgressBar;
Instead of trying to reference the progressbar control, I simply bound data to it and updated the data:
<ProgressBar x:Name="pb1" Value="{Binding XPath=#Progress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="0" Maximum="100" Height="5px" Margin="0,0,0,0" Width="145"/>
Works as expected.

list picker gives error when selting selected item

I have a listpicker control that has a list of meals. This control is populated using following code where viewModelMeal returns a collection of type Meal
After that I get the Diet data from database and that also has a column name MealId. Now when I try to set the selected item of listpicker control with that mealid it gives me error that "SelectedItem must always be set to a valid value". Here is the function setting the selected item of listpicker
and XAML code
<toolkit:ListPicker Name="lpMeal" Height="60" ItemsSource="{Binding}" VerticalAlignment="Bottom" Background="Black" FullModeHeader="Select your Meal" Foreground="White" ExpansionMode="FullScreenOnly" Margin="5,0">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel Name="listpickerStackpannel" >
<!--<TextBlock Text="{Binding mealId}" Visibility="Collapsed"></TextBlock>-->
<TextBlock Text="{Binding mealName}" TextAlignment="Center" FontFamily="Times New Roman" FontSize="30"></TextBlock>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<StackPanel Name="listpickerStackpannel" Margin="10">
<!--<TextBlock Text="{Binding mealId}" Visibility="Collapsed"></TextBlock>-->
<TextBlock Text="{Binding mealName}" TextAlignment="Center" FontFamily="Times New Roman" FontSize="30"></TextBlock>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
To elaborate on Chubosaurus Software's comment.
You need to set the SelectedItem to a value that is in the list that the lpMeal ItemsSource is bound to. In your case:
lpMeal.SelectedItem = DietViewModel.GetDefault().GetItem(ID);
Therefore you are setting the SelectedItem to a member of the list in it's ItemsSource.

How dynamically create PanoramaItem control in c#?

**<controls:PanoramaItem Header="first item">
<!--Double line list with text wrapping-->
<ListBox Margin="0,0,-12,0" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="150">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="Name" Text="Name: " TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" Margin="5,0,0,0"/>
</StackPanel>
<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
<TextBlock Text="{Binding LineThree}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
<TextBlock Text="{Binding LineFour}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PanoramaItem>**
This is .xmal Part. but I have to do this in c#.Then Please Help me how i am do this.
ListBox listBox = new ListBox();
listBox.Margin = new Thickness(0, 0, -12, 0);
listBox.SetBinding(ListBox.ItemsSourceProperty, new Binding("Items"))
CreateItemTemplate(listBox);
PanoramaItem pi = new PanoramaItem();
pi.Header = "first item";
pi.Content = listBox;
When implementing CreateItemTemplate you have two choices, either create the DataTemplate programmatically or create it in a ResourceDictionary as a resource and use that resource. The latter is by far the easiest and best way to do it.
To do it programatically see How to define a DataTemplate in code?
To use a resource you can something like this
public void CreateItemTemplate(ListBox listBox)
{
object myDataTemplate = FindResource("myDataTemplateResource"); // This only works if the resource is available in the scope of your control. E.g. is defined in MyControl.Resources
listBox.SetResourceReference(ListBox.ItemTemplateProperty, myDataTemplate);
}

How to Save to Database from ListBox?

I know how to save to my database from a datagrid's selected row, but I want to save all records from my list box to the database. Here is the related xaml for the ListBox:
<UserControl.Resources>
<DataTemplate x:Key="EventDataTemplate">
<StackPanel Name="OuterStackPanel">
<TextBox Text="{Binding Title}" Name="TextBoxTitle"/>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding BeginDate}" Name="TextBoxBeginDate"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding EndDate}" Name="TextBoxEndDate"/>
</StackPanel>
<TextBox Text="{Binding Venue}" Name="TextBoxVenue"/>
<TextBox Text="{Binding Location}" Name="TextBoxLocation"/>
<TextBlock Name="TextBlockID" Text="{Binding id}"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<ListBox x:Name="AllEventsListBox" ItemTemplate="{StaticResource EventDataTemplate}"/>
With my DataGrid method, I use this codebehind to save its row's related TextBoxes to the database:
MyServiceClient client = new MyServiceClient();
client.UpdateEventCompleted += new EventHandler<UpdateEventCompletedEventArgs>(client_UpdateEventCompleted);
singleEvent.id = int.Parse(LblID.Content.ToString());
singleEvent.Title = TextBoxTitle.Text;
singleEvent.Location = TextBoxLocation.Text;
singleEvent.BeginDate = TextBoxBegin.Text;
singleEvent.EndDate= TextBoxEnd.Text;
singleEvent.Venue = TextBoxVenue.Text;
client.UpdateEventAsync(singleEvent);
However, I would like to save all of the altered text from my generated ListBoxItems, instead of just one row at a time from my DataGrid method.
Is this possible?

Accessing a TextBlock which is contained inside a ListBox

I have a textblock which is inside a listbox and I am trying to write an if statement which is dependant on the contents of this textblock. I am trying to get the data from the TextBlack which I have named "category1" however when I try to write my if statement I am getting a message which just says
"the name category1 does not exist in the current context"
I tired moving that TextBLock out of the ListBox and it works fine but wont work while its inside there. Does anyone know how to reference this textblock.
Here is the my XAML code
<ListBox x:Name="HINList" Margin="0,300,-12,0" ItemsSource="{Binding Details}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding HINNumber}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding CategoryLetter}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="category1" Text="{Binding Category1}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="{Binding Category2}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="{Binding Category3}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Assuming you're writing your if statement in the code behind file, wouldn't something like:
if(((WhateverTypeIsInDetailsCollection)HINList.SelectedItem).Category1 == something) {
// then do whatever you want
}
As Russell pointed out there is a category1 item for every entry in the list. I assume you wanted to do something with the selected item.
This is due to xaml namescopes. The names inside a DataTemplate are in a different namescope than outside, that's why you can't access them (what #Russell pointed is part of why it's done this way).
I think that you want to access that field for the "Category1" property on the selected item of the HINList ListBox that is bound to the Details collection. What you can do is set the binding on the Category1 to be two way, and bind the SelectedItem of the ListBox to a Detail item like so:
xaml:
<ListBox x:Name="HINList" ItemsSource="{Binding Details}"
SelectedItem={Binding SelectedDetailItem, Mode=TwoWay}>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding Category1, Mode=TwoWay}" TextWrapping="Wrap" .../>
<!-- the other fields -->
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
code-behind
if(SelectedDetailsItem.Category1==...)
{
....
}
Hope this helps :)

Categories

Resources