ListPicker? I hardly even know 'er! [A detailed overview of the Windows Phone Toolkit's ListPicker control]
**
This blog has moved to a new location and comments have been disabled.
All old posts, new posts, and comments can be found on The blog of dlaa.me.
See you there!
Comments
Anonymous
November 03, 2010
Hello, Delay. I want to know, if ListPicker can have a custom choosing page just like DatePicker have which is described in your blog before? You click the toolkit, navigate to your custom page, choose one option, and navigate back with a value by "Navigate.GoBack();"? Can we do that? And because there is no ApplicationBar in the choose page, is there a way to implement one? Thanks.Anonymous
November 03, 2010
Its great to have these controls out there fir us all to use. It's a shame that the animation of the items appearing in the full page list isn't present, same with the quick jump lists, although those being popups kinda explain why the animations were left out (popups are not hardware accelerated).Anonymous
November 03, 2010
Pebo, ListPicker doesn't support customization of the popup in the same way that DatePicker/TimePicker do, but it does support customization of the popup content via re-Templating. This is actually the typical approach for Silverlight control tweaking and it's how I would have done things for DatePicker/TimePicker if it weren't for the fact that they couldn't use Popup due to the lack of hardware acceleration at present. You won't be able to add an ApplicationBar (without modifying the ListPicker code) because ListPicker specifically turns it off for the popup, but you should be able to customize the popup itself to your liking. Hope this helps!Anonymous
November 03, 2010
Martin Anderson, Thanks for understanding. :) That said, you're welcome to add such animations yourself if they work well in your scenario. And if you do, I'd love to see a blog post showing everyone how to do so, too!Anonymous
November 15, 2010
Strange thing, why don't the controls I placed below the listpicker, get pushed down when the list picker is expanded? M I missing out something? :(Anonymous
November 15, 2010
Hi David, My app has been rejected certification because I use a ListPicker and when I press the back button the page goes back, instead of the ListPicker closing. Is there a work around for this? I've found no programmatic way to see if the ListPicker is open, and no programmatic way to close it either. Please help me, this is an awesome feature and I need it in my app, but it's getting rejected because of it. Thanks, Juliana PeñaAnonymous
November 16, 2010
Mejo18, If you use a StackPanel (as the public samples and my samples above do, content below the ListPicker will automatically slide down as it animates to its Expanded state. If you use a different Panel, that may not happen. Hope this helps!Anonymous
November 16, 2010
Juliana, I'm very sorry for the trouble! The issue you're reporting has come up twice before (that I know of) and is already fixed for the next Toolkit release. You can read more here: silverlight.codeplex.com/.../7643 For now, you can apply the application-level workaround I describe in the work item OR apply the source-level workaround in the associated changeset. There will be a Toolkit refresh soon (which is why I haven't blogged about this yet) which will get you the fix for free simply by installing the latest Toolkit build. But in the meantime, either of these approaches should work for you - as they've worked for others. Thanks very much for your patience - and sorry again for the inconvenience!Anonymous
November 29, 2010
The comment has been removedAnonymous
November 30, 2010
The comment has been removedAnonymous
December 03, 2010
How do you add items to list picker control by code behind. I tried ListPicker.Items.Add(i.ToString()); and does not seem to work.Anonymous
December 03, 2010
I figured out how to add list items from code behind. For some one who might have a similar problem, my solution is given below. I created an observable collection Code behind int startyear 2000; int endyear 2010; ObservableCollection<string> yearlist = new ObservableCollection<string>(); for (int i = endyear; i >= startyear; i--) { yearlist.Add(i.ToString()); } YearListPicker.ItemsSource = yearlist; XAML <toolkit:ListPicker Margin="4,4,4,4" x:Name="YearListPicker" Header="Year" > </toolkit:ListPicker>Anonymous
December 04, 2010
vijay, ObservableCollection (via ItemsSource) is definitely the most flexible option for ItemsControl subclasses like ListPicker. However, your first example using Items.Add should work, as well. You don't say what about that didn't work for you, but one thing to remember with all ItemsControl subclasses is that you can't mix Items and ItemsSource - you need to pick one method of providing the items and then use that exclusively or else an exception results. Glad you got this going! :)Anonymous
December 04, 2010
Delay, I got it working. You are right. I was making the mistake of mixing up items and ItemSource. Both the following scenarios work:
- When I have a list and add items to the listpicker using foreach.
- Bind list directly to listpicker . I think I was getting into trouble when I mixed up both. Thanks. Vijay
Anonymous
December 09, 2010
How do you determine the value for the selected item? For example: MessageBox.Show(MyListBox.SelectedItem.ToString()); only yields the name of the object type, not the actual data at the selected location. How do you get the actual value of the selected item? some suggest using something like: ((System.Data.DataRowView) lstSelectedItems.Items[i]).Item[0].ToString() but DataRowView doesn't seem to be available in silverlight for WP7. Appreciate any advice.Anonymous
December 10, 2010
benneh, ListBox.SelectedItem is the selected item. Calling ToString() on most objects simply outputs the object's name, so that's what you're seeing here by calling ToString() on the SelectedItem. If you cast to the correct type, you'll be able to access the object's properties/methods. For example: "MyObject o = (MyObject)(ListBox.SelectedItem); o.Whatever();" Hope this helps!Anonymous
December 10, 2010
The comment has been removedAnonymous
December 10, 2010
ListPicker with Multiple Check Boxes, This sounds like it would be different than the way every other ListPicker on the phone works, and therefore, I'd probably advise against it. Easier (and more standard) might be a ListBox with CheckBoxes inside it - or just use the Multiple selection mode that ListBox already has and skip the CheckBoxes altogether. One other idea would be something like the Inbox implements where the CheckBoxes are normally hidden off the left of the screen and slide in when needed. Hope this helps!Anonymous
December 10, 2010
Thanks Delay, yes that did help. I was binding to the data from blend, no idea what class it used, so instead I created my own class and bound programatically. I was then able to type cast correctly the .selectedItem and got what I needed. thanks for steering me in the right direction.Anonymous
December 15, 2010
I've got this wired up in my app, but am wondering about what the best practice is for displaying localized string values in the listbox, but having the actual bound value be a number. For example, I want to have a ListPicker that shows the following: 7 days 14 days 30 days But I want to store in my bound value 7, 14, or 30 so I can use it as an app setting. Any pointers on the right design pattern for this? Thanks!Anonymous
December 16, 2010
Neil Enns, The easiest way is probably to use an IValueConverter - let your ListPicker items be of type Int32 and then use the IValueConverter in your ItemTemplate DataTemplate to create the friendly form as part of the Binding to a TextBlock's Text property (or similar). The ConvertTo method of the IValueConverter can either do a simple 'value + "days"' or it can be more sophisticated and look up the "days" string based on the current UI settings (ideally via the standard RESX localization process). Hope this helps!Anonymous
February 02, 2011
Hi, my app was rejected as the listpicker becomes 'transparent' when the phone is running on the light (white) color theme. Any quick fix for this? ThanksAnonymous
February 02, 2011
The comment has been removedAnonymous
February 02, 2011
The comment has been removedAnonymous
February 03, 2011
Vlad A, At an application level (vs. a control level which is much more constrained), solving the "ListPicker at the bottom of the page" problem shouldn't be too difficult - because the application is in a place to know when the ListPicker mode changes and also know which ScrollViewer should be adjusted to accomodate its new size. If you start by detecting when the ListPicker mode changes (you can watch the ListPickerMode DependencyProperty), then it should be a pretty straightforward matter of adjusting the relevant ScrollViewer's VerticalOffset to accomodate the new size if/when the user is already at the bottom. Hope this helps!Anonymous
February 19, 2011
The comment has been removedAnonymous
February 19, 2011
swordfish8, I'm sorry to hear that - it's the first complaint I've heard in the months since I posted this sample. I've just downloaded it myself and tried again on both the original developer tools and the January update and it continues to run fine on my machine (which is configured similarly to yours). Maybe if you could share the specific steps you're following to hit this crash? Otherwise, please try it on a different machine - I'm wondering if maybe something about your specific configuration is causing this problem. Thanks!Anonymous
March 01, 2011
Hey, David. I have the same problem as one of the posters above; with the light theme, when the ListPicker is dropped down, it turns "white" as expected, but is transparent, so all of the UI items below it (other ListPickers, boxes, text, etc.) show right through, obscuring the text in the ListPicker. I haven't submitted yet because I did this testing and noticed it. Trying to figure out how to control the background transparency when the ListPicker is "open" (i.e. selected). Starting on that now. Any insight into this would be appreciated. I can also send you screenshots if you want to see it. Thanks. Bill~Anonymous
March 01, 2011
Bill Williams, The conventional approach with ListPicker (i.e., what matches the in-ROM experience) is to put it in a StackPanel - so when it expands, the content below is automatically pushed down and there's no possibility of overlapping to be concerned with. I've recommended that in the past and people reporting the overlapping problem have generally had success with it. This is also what all my samples show. As I said in a reply to a comment above, the semi-transparency issue is something that comes directly from using the appropriate phone styles - but if you don't get yourself into an overlapping situation (i.e., by using StackPanel), it shouldn't be an issue. :) Hope this helps!Anonymous
March 11, 2011
I am trying to use ListPicker.SelectedItemProperty. I am getting below error. any help on this is appreciated. SelectedItem must always be set to a valid value.Anonymous
March 11, 2011
The comment has been removedAnonymous
March 14, 2011
The comment has been removedAnonymous
March 14, 2011
Samuel, What I think is going on is that full mode uses a ListBox which doesn't have its DisplayMemberPath bound to the ListPicker's same-named property. You could re-Template to hook that up, or you could just provide a simple FullModeItemTemplate with a TextBlock's Text property set to {Binding} for the equivalent effect. I have similar examples in the post above. Hope this helps!Anonymous
March 15, 2011
Totally missed that part of it. Thanks David, that's exactly what I needed.Anonymous
April 05, 2011
David, I have wired up a MyListPickerSelectionChanged event to fire whenever the user chooses a different item. As you described above, it fires when the list is initially populated and all is fine. When the user changes the selection, my event fires, but the property that is bound to the ListPicker still has the old value so all of the code that runs in the MyListPickerSelectionChanged handler operates on the old value. When the handler exits, the bound property is then updated, too late for all of my code from the handler. So, I have inserted: _viewModel.BoundProperty = (string)MyListPicker.SelectedItem; and this solves the problem, but it seems kludgy. Is there a better way? Thanks in advance! Robert BernsteinAnonymous
April 05, 2011
RobertBernstein, Your technique seems reasonable to me given the problem you describe. And I agree with you that the underlying behavior appears wrong - that's not how ListBox works on WPF (I verified just now). I'm curious if ListBox behaves the same way on WP7 or not (I suspect not, but I'm not set up to test it right now), but either way it seems like ListPicker could do better. Sorry for the trouble - thanks for sharing your workaround! :)Anonymous
April 05, 2011
Thanks for responding so quickly, David.Anonymous
June 28, 2011
The comment has been removedAnonymous
June 28, 2011
photoshoper, If you put the ListPicker and its surrounding controls in a StackPanel, you'll get the desired behavior automatically. This is what all the samples in the sample project I link to above do, so you can look there to see what I mean and verify it does what you want. Hope this helps!Anonymous
June 28, 2011
oh okay.. thanks David!! i didn't use StackPanel because i didn't know what it did and my app. worked without it. i'll give it a shot. thanks again!Anonymous
July 26, 2011
The comment has been removedAnonymous
July 27, 2011
PedroLamas, As you discovered, StackPanel was used instead of VirtualizingStackPanel for a very specific reason. If you're okay changing the selection behavior like you discuss in your post, then your changes seem pretty helpful! :) Thanks very much for sharing this!Anonymous
September 17, 2011
Would be great to have an update of this post for August release of the toolkit. Where is ItemCountThreshold? best regards, JacintoAnonymous
September 18, 2011
Jacinto Perez, I left the Silverlight Toolkit team a while ago, so I'm not up to date on the latest changes. That said, I think I recall seeing that ItemCountThreshold was deliberately removed, though I don't know why - clearly I thought it was useful because I put it there in the first place! :) I've added a note to my TODO list to look into this and maybe discuss the changes, but it'll probably be a while before I get around to that.Anonymous
November 06, 2011
This is great, but it doesn't flow well with StackPanel, the pop-up selector is hidden if it goes outside the StackPanel borderAnonymous
November 06, 2011
nezbo, Thank you for the feedback! I don't think I've heard of this problem, but I know there have been changes to ListPicker since I originally wrote this post [and it :) ]. I'll pass your feedback on to the current owner to follow up with you. In the meantime, it might be helpful if you are able to come up with a simple demonstration of the problem (for example, in a new, otherwise empty, project). Thanks!Anonymous
November 06, 2011
nezbo, I checked with Jeff Wilcox (http://www.jeff.wilcox.name/) and he tells me the bug you're seeing has been fixed for the next release of the Toolkit and is already available from the CodePlex web site's "Source Control" tab. I hope this helps!Anonymous
December 13, 2011
David, I have a listpicker which is being fed with a list of strings using the ItemsSource property. On clicking the list picker in the app, I get navigated to a pop-up screen/fullscreenmode and I cannot seem to change the background of this screen from black. I've tried implementations such as: <toolkit:ListPicker.FullModeItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" Background="Goldenrod" Height="768" Width="480"> <TextBlock Text="{Binding BindsDirectlyToSource=True}" Width="150"/> </StackPanel> </DataTemplate> </toolkit:ListPicker.FullModeItemTemplate> but they just put a stackpanel, around the list and not the entire screen and on specifying the height and width of the stackpanel to match the phone, the list is not displayed correctly. How would I change the background of the pop-up screen? Also the font of the strings in the list?Anonymous
December 13, 2011
Adi, To make the kind of customizations you're talking about, you'll want to re-Template the control (just as you would for significant changes to Button, etc.). In this case, I think you want to start by looking at the "FullModePopup" element in the ListPicker template. Here's an online link to get an idea what I'm talking about: silverlight.codeplex.com/.../56962 Hope this helps!Anonymous
January 15, 2012
Hi David, I have a doubt regarding settings page of my app. I have a set of ListPickers, to choose different font settings. I'm using IsolatedStorage to save and load my settings. Everything is working fine, except when i change the settings and re-navigate to the settings page, although the listPickers selection is correct about the last setting, but it shows the first item of the listPicker instead of the selectedItem. <toolkit:ListPicker Name="fontColor" Grid.Row="3" Header="Foreground" CacheMode="BitmapCache" ItemTemplate="{StaticResource colorChooser}" FullModeItemTemplate="{StaticResource colorChooserFull}" SelectedIndex="{Binding Source={StaticResource appSettings}, Path=colorSetting, Mode=TwoWay}"/> What am i missing?Anonymous
January 16, 2012
UmangGupta, There have been changes to ListPicker since I wrote this post, so I'm not sure why you're seeing that behavior offhand. :( You might try the sample app above to see if it demonstrates a similar problem. Also, you might look at how SelectedIndex is being handled - I wonder if the TwoWay Binding is interfering during control initialization? To check that, you might experiment with setting the SelectedIndex property after the page has loaded and see if that makes a difference. Hope this helps!Anonymous
June 27, 2012
The comment has been removedAnonymous
June 27, 2012
aswthastar, The sample code was written on and tested with the 7.0 SDK and the version of ListPicker available at the time. It should work the same on the 7.1 SDK and more recent versions of ListPicker, though I haven't specifically tested that. What versions of the SDK/Toolkit are you using? Have you made any changes, or are you seeing this problem with the original sample code? If you've made changes, I'd suggest looking at whether they may have broken something - if not, please let me know, I can have a quick look to see what might be going wrong. Thanks!Anonymous
June 28, 2012
<toolkit:ListPicker Header="Rating" FullModeHeader="CHOOSE RATING" ItemsSource="{Binding Ratings}" ItemCountThreshold="0"/> <toolkit:ListPicker Header="Spectrum" ItemsSource="{Binding Rainbow}" ItemTemplate="{StaticResource RainbowTemplate}" ItemCountThreshold="100"/> when i put this code , what should i do to put what i want ? if i put the code like this my program crashes and i have to make a new one cuz it delete almost evertfiles ... ThanksAnonymous
June 28, 2012
João marcelo, The snippet you show above references the "RainbowTemplate" resource which must be available at runtime in order for the XAML to parse successfully. That resource part of the sample code, so that's why the sample works - if you want to reuse this XAML in a different application, you'll need to copy over the definition of RainbowTemplate as well. Hope this helps!Anonymous
March 23, 2013
I have question... Why every time I selected a display always shows first that one ???????? who tell me why ???? var City = JsonConvert.DeserializeObject<city>(e.Result); this.Dispatcher.BeginInvoke(() => { this.CityPhoneTextBox.ItemsSource = City.City; } private void CityPhoneTextBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { ListPicker picker = sender as ListPicker; //if(picker!=null&&picker.SelectedIndex>0) //{ // picker.SelectionChanged += picker_SelectionChanged; // object selected = picker.SelectedItem; // picker. //} if (this.CityPhoneTextBox.SelectedIndex >= 0) { if (this.CityPhoneTextBox.SelectedItem != null) { var city = (tangcruises.Model.Convert)CityPhoneTextBox.SelectedItem; var idcity = city.id; //this.CityPhoneTextBox.SelectionChanged+=CityPhoneTextBox_SelectionChanged; var cityName = city.name; cityID = idcity; cityname = cityName; //this.CityPhoneTextBox.SelectedIndex = this.CityPhoneTextBox.SelectedIndex + 1; // this.CityPhoneTextBox.Items = this.CityPhoneTextBox.SelectedItem; //this.CityPhoneTextBox.SelectedItem = cityname.ToString(); // ListPickerItem selectedItem = this.CityPhoneTextBox.ItemContainerGenerator.ContainerFromItem(picker) as ListPickerItem; // this.CityPhoneTextBox.GetBindingExpression.(ListPicker.SelectedItemProperty).UpdateSource(); // this.CityPhoneTextBox.SelectedItem = =SaveOptions.OmitDuplicateNamespaces; //picker.SelectionChanged -= picker_SelectionChanged; //object select = picker.SelectedItem; //picker.Items.Remove(select); //picker.Items.Insert(0, select); //picker.SelectedIndex = 0; //picker.SelectionChanged += picker_SelectionChanged; } return; } else { return; } }Anonymous
March 23, 2013
thank you ..Anonymous
March 24, 2013
The comment has been removedAnonymous
November 10, 2013
class CustomItem { public string Caption { get; set; } } public partial class MainPage : PhoneApplicationPage { // Constructor public IEnumerable SunSigns { get; set; } public MainPage() { InitializeComponent(); SunSigns = new List<CustomItem>() { new CustomItem() {Caption = "Option 1"}, new CustomItem() {Caption = "Option 2"}, new CustomItem() {Caption = "Option 3"}, new CustomItem() {Caption = "Option 4"}, new CustomItem() {Caption = "Option 5"}, new CustomItem() {Caption = "Option 6"}, new CustomItem() {Caption = "Option 7"}, new CustomItem() {Caption = "Option 8"}, new CustomItem() {Caption = "Option 9"}, new CustomItem() {Caption = "Option 10"}, new CustomItem() {Caption = "Option 11"}, new CustomItem() {Caption = "Option 12"} }; then I did binding of the ListPicker ItemSource to SunSign, bt instead of showing Option 1, Option 2 ...... "ListPickerBindingDemo.CustomItem" is shown. The XAML is <toolkit:ListPicker Header="Choose your Sun Sign" FullModeHeader="Choose Your Sun Sign" ItemsSource="{Binding SunSigns, ElementName=thisPage}"> </toolkit:ListPicker> what am I doing wrong here?? Please HelpAnonymous
November 10, 2013
Anika, You need to do one of the following:
- Provide a ToString method on CustomItem
- Provide a ListPicker.ItemTemplate that renders the Caption property of CustomItem
- Set ListPicker.DisplayMemberPath (if available) Hope this helps!
Anonymous
December 07, 2013
Hi David, I'm glad that you are still maintaining this article. I'm trying to use the ListPicker from the latest version of Windows toolkit. And I have problem when trying to set data binding with the SelectedItem, I'm just wandering how you make it work in your code sample: <toolkit:ListPicker Header="Network" ItemsSource="{Binding Networks}" SelectedItem="{Binding CurrentNetwork, Mode=TwoWay}"/> What's the type of the CurrentNetwork you bind with the SelectedItem? When I try with a string, it fails. Data binding with SelectIndex does work, however, it won't display the correct item in the ListPicker. Any hint would be appreciated. Thanks, MaxAnonymous
December 08, 2013
Max Meng, While I haven't used recent versions of the Toolkit, you can download my sample code and try it out. In the case of CurrentNetwork, it's bound to an instance of the (custom) Network class that's part of the sample. Hope this helps!Anonymous
January 01, 2014
Sorry for the later response, I forgot to subscribe this blog article. I downloaded your sample code, however it doesn't include the Toolkit you used, if I install the recent versions of the Toolkit, it should behave the same way. Although I still get the "SelectedItem must always be set to a valid value" error in the designer, it does compile, and my app also runs fine. So, I think I can live with it, thanks for your attention!