I am trying to bind a list of objects to a list control for a Windows Phone 8 app which also contains another list within it. I have tried to find out how to set this out so that when selecting an item from the parent list the child list is then loaded into a separate list control but cannot find any details. Any help would be most appreciated as I have hit a dead end with this.
I am trying to use lists as below:
List which then contains a List which also contains a List. I need to setup an initial list of stations which the user will select one, which will then populate another list with the platforms, and then selecting a platform will load the list of trains.
You should bind your outermost list to the outermost listbox (or whatever list control you are using).
After that you can bind the selecteditem of the outerlist to the child listviews.
Here's an example:
<ListBox ItemsSource="{Binding OuterList}" x:Name="OuterList" SelectionMode="Single" />
<ListBox ItemsSource="{Binding ElementName=OuterList, Path=SelectedItem}" x:Name="Innerlist1" />
<ListBox ItemsSource="{Binding ElementName=InnerList1, Path=SelectedItem}" />
Related
This question is related to MVVM project structure.
For displaying data in a ListView I use a DataTemplate. The ItemsSource for the ListView is an ObservableCollection(of Person). Nothing special so far.
But in the DataTemplate I want to display a the State property of each Person in a ComboBox, where the actual value is displayed, and the user can choose another State.
The State comes from States, that is an ObservableCollection(of State).
In order to show all the States, I need to Bind the DataContext to the "toplevel" of the ViewModel. But how do I come down to the individual person again, that is shown in the DataTemplate? Or do I need another approach for this problem?
In XAML I have this:
<ComboBox DataContext="{Binding DataContext, ElementName=pageRoot}" ItemsSource="{Binding States}" DisplayMemberPath="Description" SelectedValue="{Binding ??????}" SelectedValuePath="ID" />
My question is: what do I need to set in order to Bind the SelectedValue correctly so that it shows the actual State per Person in the text-field of the Combobox?
Got it!
For the ItemsSource of the ComboBox I need the "higher" level of the DataContext hierarchy. Instead of Binding the entire ComboBox to that DataContext, I only needed to Bind the ItemsSource to that level.
The corrected code now looks like so:
<ComboBox
ItemsSource="{Binding DataContext.States, ElementName=pageRoot}"
DisplayMemberPath="Description"
SelectedValue="{Binding State.ID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="ID"
Trial and error works out! :-)
I'm using XAML for a windows phone apps, and I'm binding a collection to graph control within the listbox Itemtemplate. Everything shows correctly except that the Horizontal axis is scaled per the data in the grid and I want them all scaled the same.
I've worked out the Maximum value - which need to establish the data binding - as its in a listbox itemtemplate I can't simply set the value in code. And for the data binding I only seem to see the elements in the collection but the value I have is not an element of the collection.
Is it possible to bind to a property/field of the page - that way I can set the value and all the grids can just bind to this property/fields.
One possible way to bind element inside ListBox item template to property of the page is by using ElementName binding. Simply name the page, then you can set binding source by page name, for example :
<phone:PhoneApplicationPage
..........
..........
x:Name="myPage">
<Grid x:Name="LayoutRoot" Background="Transparent">
<TextBlock Text="{Binding ElementName=myPage, Path=Name}" />
</Grid>
</phone:PhoneApplicationPage>
Above sample will display text "myPage" in the TextBlock. That way of binding also works for elements inside DataTemplate for ListBox item.
I am developing a windows 8 app. And I want to display a GridView inside of another GridView item template. And I have added a visibility binding to the inner GridView, but the binding doesn't work when wrapping the GridViewItems in the outer GridView. It works when i use a simple ListView or GridView without any wrapping.
This is the main GridView with wrapping
<GridView
Name="feedGridView"
Background="Transparent"
SelectionMode="None"
ItemTemplate="{StaticResource MyFeedGridView}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Height="600" Orientation="Vertical" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
The style for "MyFeedGridView" which contains another GridView
<DataTemplate x:Key="MyFeedGridView">
<Grid HorizontalAlignment="Left" Width="500">
<StackPanel x:Name="gridViewStackPanel" Orientation="Horizontal" >
<GridView
HorizontalAlignment="Right"
x:Name="myFeedGridViewInListView"
ItemTemplate="{StaticResource MyFeedGridViewInListView}"
ItemsSource="{Binding listContent}"
Height="100"
Visibility="{Binding listContent,Converter={StaticResource FeedListToVisibilityConverter}}"
SelectionMode="None"
Width="400" />
</StackPanel>
</Grid>
</DataTemplate>
I am using a converter to hide or show the inner GridView. The below is the converter that i am using
public object Convert(object value, Type targetType, object parameter, string language)
{
List<ContentList> contents = value as List<ContentList>;
return (contents != null && contents.Count > 0) ? Visibility.Visible : Visibility.Collapsed;
}
My problem is that the inner GridView gets hidden for all the items or gets visible for all the items irrespective of the listcontent that I have bound.
I have noticed is that this is happening only when I set the ItemsPanel. If I remove the VariableSizedWrapGrid property then it's working as expected. But I need to wrap the items after each column so I can't do away with it.
Please let me know if you have any clue why this is happening.
Thanks
EDIT:
Attaching image of how the grid view items should be arranged. If you see the first item of the grid view, it has another grid view inside the grid view item representing songs. So this inner grid view will be empty for some items and populated for some. So I had written a visibility converter to show and hide the inner grid view. And when am using the converter,if the first grid view item has inner grid view items(songs then it will show inner grid view for all the items and if the first grid view item doesnt have any inner grid view items(songs) then it hides inner grid view for all the main grid view items.
Let me know if its not clear.
The problem with a GridView is that it uses the same size for all its GridViewItems by default. You can use a VariableSizedWrapGrid as its ItemsPanel, but that will disable virtualization and so you won't be able to use your GridView with a large number of items (more than a few dozen) without incurring performance cost.
For your scenario you could use a GridView with a non-uniform ItemsSource - one where some items represent the main list item and some that represent lists of songs and use the ItemTemplateSelector to specify which template to use for which type of item. It's not ideal of course, but this is what your easiest option is. One problem is that some of these song lists might end up orphaned in a different column than the item they are associated with, so for the ugly workaround you might need to figure out the number of items per column and in the list also include empty items or rearrange the items so that the empty-end-of-column items are filled with items that don't have any song lists associated with them.
A better option might be to use a VariableSizedWrapGrid as ItemsSource or simply use a manually populated Grid and add a more... item at the end that opens a ListView, since vertical lists IMHO are easier to scroll than horizontal GridViews. You would still need to use a non-uniform ItemsSource and ItemTemplateSelector to get the desired layout and keep virtualization of the list, but that's what you get.
I have a ComboBox with the following XAML
<ComboBox Name="CompanyComboBox"
ItemsSource="{Binding Path=CompanyList, Mode=OneWay}"
SelectedItem="{Binding Path=CurrentCompany, Mode=TwoWay}"
DisplayMemberPath="Name" />
Problem:
The selected option on 'company' is persisted, but never gets displayed on load. What's missing or going wrong, or what have I forgotten to do?
CompanyList has data, and the ComboBox does get populated
The selection on the ComboBox does save to the database via the TwoWayBinding
More code is on pastebin.com, the ViewModel and the Company class code.
I have tried the following suggestions, that have so far not solve the issue:
Two-way bind a combobox to a simple string array Order of ItemSource and SelectedValue properties on were correct
ComboBox.SelectedValue not updating from binding source alternating between 'SelectedValue' and 'SelectedIndex' - neither works
Silverlight 4 Combobox with selectedValue using MVVM-Light raising PropertyChanged before setting new value also didn't help
Adding/Removing 'IsEnabled="{Binding IsReady}' on the ComboBox didn't help either
Adding SelectedValuePath="Name" or ="Value" stopped the save from working
You need to overwrite the Company.Equals() method to return true if the object's data is the same.
By default, it only returns true if the two company objects being compared share the same spot in memory, and I am guessing that your CurrentCompany object does not point to an object in CompanyList, so the SelectedItem is being set to null
Check that the instance assigned to CurrentCompany is the actual one contained in CompanyList and not a duplicate of it.
You can try this:
after populating CompanyList in your ViewModel, set the CurrentCompany to the first company, or a dummy item that says , or depending on your context.
Can we take a look at the view model please? Until this information is not present, may give following suspections.
CurrentCompany property is not public or is not a property.
View model doesn't implement INotifyPropertyChanged interface.
Setter of CurrentCompany property doesn't contain PropertyChanged event notification.
I have a WPF combobox control bound to a edm field in a database table. This works fine except that it enters the first value in the control when it starts which is not wanted. Heres the xaml
<ComboBox x:Name="cbMeasure"
Width="104"
ItemsSource="{Binding Source={StaticResource ddMeasureViewSource}}"
DisplayMemberPath="Measure"
IsSynchronizedWithCurrentItem="True"
SelectedValuePath="Measure"
SelectedValue="{Binding Measure1}"/>
If I just hard code the control it doesn't put the first value in the variable. Heres what that xaml looks like
<ComboBox x:Name="cbMeasure" Width="104" Text="{Binding Measure1}">
<TextBlock Text="one"/>
<TextBlock Text="two"/>
<TextBlock Text="three"/>
<TextBlock Text="four"/>
</ComboBox>
What do I have to do to make the database bound combobox start with an empty value the way the textbox combobox does? This is a problem as it puts the first value in the SelectedValue bound to a variable (Measure1).
The db table ddMeasure looks like:
RID Measure
--- -------
1 One
2 Two
3 Three
4 Four
so "One" in put into the ComboBox selection and Measure1 variable is populated as well.
OK I found the solution to this. You have to set the property IsSynchronizedWithCurrentItem to false which I thought I had tried but I think I just removed that property and the default must be true. So the xaml looks like
<ComboBox x:Name="cbMeasure"
Width="104"
ItemsSource="{Binding Source={StaticResource ddMeasureViewSource}}"
DisplayMemberPath="Measure"
IsSynchronizedWithCurrentItem="False"
SelectedValuePath="Measure"
SelectedValue="{Binding Measure1}"/>
Hope this helps others who try to find info on this type of binding.