WPF fill Listbox with collection member property - c#

I am working on list of Recipes showed in some sort of list in my WPF app.
I have a collection of recipes
public Cookbook()
{
RecipeList=new ObservableCollection<Recipe>();
AddRecipe(new Recipe("Food1", 0, null));
}
each recipe has property called Name.public string Name { get; set; }
What i am doing now is that i populate list with this collection
<ListView x:Name="CategoriesListBox" Margin="10,0,10,0" ItemsSource="{Binding RecipeList}"
Loaded="CategoriesListBox_OnLoaded"
SelectionChanged="CategoriesListBox_SelectionChanged">
<ListBox.DataContext>
<Implementation:Cookbook/>
</ListBox.DataContext>
</ListView>
Which of course results into list populated with object names - i want recipe names in the list. Is there any way to show property Name in Listbox instead?
(I am looking for XAML solution - no code behind)
// I already tried ListView and nested Gridview as a solution - this works but this also creates unnecesary grid and header fields on the top.
<ListView x:Name="CategoriesListBox" Margin="10,0,10,0" ItemsSource="{Binding RecipeList}"
Loaded="CategoriesListBox_OnLoaded"
SelectionChanged="CategoriesListBox_SelectionChanged">
<ListBox.DataContext>
<Implementation:Cookbook/>
</ListBox.DataContext>
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name, Mode=OneWay}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
Thanks

Use the DisplayMemberPath property of the ListView.
Set it to Name
DisplayMemberPath="Name"
https://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.displaymemberpath(v=vs.110).aspx

Use a ListBox instead of a ListView, and set its DisplayMemberPath property:
<ListBox ItemsSource="{Binding RecipeList}" DisplayMemberPath="Name" .../>
Or set its ItemTemplate property:
<ListBox ItemsSource="{Binding RecipeList}" ...>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Related

Databinding to combo box WPF XAML

I'm trying to bind data to a combo box. The data is names from a table from database. Getting the data from the database works fine as I have tried to bind it to a List View and it displays fine. My problem is binding it to a combo box, it doesn't show anything.
Can anyone see where I have went wrong?
My code is the following...
public string FullName
{
get
{
return String.Format("{0} {1}", _customer.ContactFirstName, _customer.ContactLastName);
}
}
and the XAML is
<ComboBox x:Name="comboBox" Grid.Row="1" Grid.ColumnSpan="2" Height="20" ItemsSource="{Binding Path=FullName}" >
The XAML for it working with a list view is the following..
<ListView
AlternationCount="2"
DataContext="{StaticResource WorkorderGroups}"
ItemContainerStyle="{StaticResource WorkorderItemStyle}"
ItemsSource="{Binding}"
Grid.Row="2" Grid.ColumnSpan="3" Margin="1,0,-1,0>
<ListView.GroupStyle>
<StaticResourceExtension ResourceKey="WorkorderGroupStyle/>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=FullName}" />
</GridView>
</ListView.View>
</ListView>
You cannot Bind a string to ComboBox. You need to bind some collection like List<T> or ObservableCollection<T> to combobox ItemsSource. Possible Duplicate.
Refer the link.
Need SIMPLE working example of setting WPF MVVM ComboBox ItemsSource based on SelectedValue of second ComboBox

Select only one item in two ListViews

I have two ListView, each bound to a specific collection in my ViewModel and I want to be able to select only one item globally.
Each ListView has its SelectedItem property bound to the same property in the ViewModel.
My probleme is as follow: when I select an item in a ListView, and then select another item in the other ListView, the first item stays selected.
I could achieve this with some code-behind, but I want to know if a pure XAML solution exists.
XAML:
<ListView SelectionMode="Single" ItemsSource="{Binding Path=MyList1}" SelectedItem="{Binding Path=MySelectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView SelectionMode="Single" ItemsSource="{Binding Path=MyList2}" SelectedItem="{Binding Path=MySelectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I finally got it working, by just replacing SelectedItem by SelectedValue.
In this use case, both properties have the same behaviour, but the latter one handles correctly the unselection if the bound selected item is not in the list.
You need to use Mode=TwoWay in your SelectedItem. It should work.

How do I bind a WPF ListView to a property of each element in a list?

I have the following binding on my ListView, which works fine:
<ListView ItemsSource="{Binding Filters}" Margin="5" Name="FiltersList" Height="100"/>
Filters is actually a type of List<LogFilter>. LogFilters have a property on them called Title. I would like to show the Title of each element in the Filters list in my ListView instead. Is this possible? Something like ItemsSource="{Binding Filters.Title}"?
Just set the ItemTemplate to display the title:
<ListView ItemsSource="{Binding Filters}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
It seems to me that you don't need to use ListView at all. For your needs ListBox with DisplayMemberPath would be enough:
<ListBox ItemsSource="{Binding Filters}" DisplayMemberPath="Title"/>

Binding combobox in DataTemplate to a different ItemSource

I have 2 ObservableCollection lists, which we can call A and B, then I have a GridView that I want to bind to list A and a ComboBox INSIDE that GridView, that I want to bind to list B.
I've set the ItemsSource property of the GridView by code: gridview.ItemsSource=A (and it works!). About the ComboBox its instance it is not available by code, I suppose because its definition it is enclosed between the DataTemplate tags; so I wonder how to bind the combo to list B, either by code or by XAML.
Follows the XAML code:
<ListView Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="lstReplacements" VerticalAlignment="Stretch">
<ListView.View>
<GridView>
<GridViewColumn HeaderContainerStyle="{StaticResource MyHeaderStyle}" Header="Wrong text" DisplayMemberBinding="{Binding Word}"/>
<GridViewColumn HeaderContainerStyle="{StaticResource MyHeaderStyle}" Header="Replacement" Width="60" DisplayMemberBinding="{Binding Replacement}" />
<GridViewColumn HeaderContainerStyle="{StaticResource MyHeaderStyle}" Header="Type" Width="30">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{??????}" DisplayMemberPath="??????" Grid.Row="1" Grid.Column="0" Name="cmbCorrectionType" Width="75" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Thanks in advance for the support!
Chris
I assume this control is in UserControl and you have set DataContext of that UserControl to the class instance where your both collections CollectionA and CollectionB resides.
You can then bind using RelativeSource:
<ComboBox ItemsSource="{Binding DataContext.CollectionB,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=UserControl}}"/>
Also you can set DataContext of ListView to the class instance and all you need to do is change AncestorType to ListView in place of UserControl in above binding.

Binding to property within the ItemsSource

I have class like the following:
class test
{
public string Name;
public string Location;
}
Through a result of query using entity framework I am getting back a collection of test objects which I am directly setting to my listbox. But using the DisplayMemberPath Iam just displaying Name value. So now the listbox is holding the whole collection of test objects but just displaying Name value.
When I am trying to bind to the selecteditem of the list box Iam getting the whole test object as a string but I just need Name value in the selecteditem result.
My XAML is as follows:
<ListBox x:Name="lbSubSelector" Height="200" DisplayMemberPath="Name" SelectedItem="{Binding Name, Mode=TwoWay}" />
My code to populate list is as follows:
LoadOperation<test> subLoadOp = context.Load(context.GetTestQuery());
lbSubSelector.ItemsSource = subLoadOp.Entities;
lbSubDistrictSelector.DataContext = SkillModel.Instance;
The DataContext to which the selectedItem is set to is having a value of the whole string representation of test object but I want the selecteditem to just return Name value as it is displaying (as i have set the displaymemberpath to Name) instead of returned the whole object in string format.
How can I achieve this?
Use following:
<ListBox x:Name="lbSubSelector" Height="200" DisplayMemberPath="Name" SelectedValuePath="#Name" />
Then you can use lbSubSelector.SelectedValue to get Name property of selected item.
see:
http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.selectedvaluepath.aspx
Please use the IsSynchronizedWithCurrentItem property on the Listbox and change the SelectedItem binding to /Name in xaml code as follows:
<ListBox x:Name="lbSubSelector" Height="200" DisplayMemberPath="Name" SelectedItem="{Binding /Name, Mode=TwoWay}" IsSynchronizedWithCurrentItem="True"/>
Rather than Using ListBox, I would suggest you using the ListView with GridColumns. Following is the snippet, you might need to remodify it accordingly. But this surely will work the way you want it to :-
<ListView Name="ListView1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding}" MouseDoubleClick="transactionListView_MouseDoubleClick" IsSynchronizedWithCurrentItem="True" >
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource gridViewHeaderColumnStyle}">
<GridView.Columns>
<GridViewColumn Width="70" Header="Name" DisplayMemberBinding="{Binding Path=Name}" />
<GridViewColumn Width="270" Header="Seller" DisplayMemberBinding="{Binding Path=Location}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>

Categories