Binding to property within the ItemsSource - c#

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>

Related

Need help trying to attach a dictionary key and value to separate ListView GridViewColumns

XAML:
<ListView Grid.Row="0" Grid.Column="2" Width="155" Height="Auto" Margin="10" ItemsSource="{Binding MedialDictionary}"></ListView>
C# ViewModel:
private Dictionary<DateTime, decimal> _medialDictionary;
public Dictionary<DateTime, decimal> MedialDictionary
{
get => _medialDictionary;
set => SetProperty(ref _medialDictionary, value);
}
The dictionary key = DateTime
The Dictionary value = decimal
WPF looks like this:
I want to have the key in one column of the list and a value in the other. I have added GridView columns inside the ListView, but do not how to bind the properties correctly (EffectiveDate, Value).
I have read much documentation, however it has not made any sense to me so I am looking for advice/solutions here.
An item in a Dictionary<K,V> is a KeyValuePair<TKey,TValue>, which is a struct with a Key and a Value property that you can bind.
In order to display a tabular layout with columns, you can use a GridView. Each colum has a DisplayMemberPath property that the corresponding property to display is bound to.
<ListView Grid.Row="0" Grid.Column="2" Width="155" Height="Auto" Margin="10"
ItemsSource="{Binding MedialDictionary}">
<ListView.View>
<GridView>
<GridViewColumn Header="Date"
DisplayMemberBinding="{Binding Key}"/>
<GridViewColumn Header="Value"
DisplayMemberBinding="{Binding Value}"/>
</GridView>
</ListView.View>
</ListView>

WPF How to display relational data in DataGrid's TextBlock like in ComboBox

When searching for help on this topic, I typically find information on how to populate a ComboBox with related data (display name in one table for the foreign key in originating table), but I am already able to do that. I am looking for a solution on how to achieve the same result in a TextBlock.
In my project I have created a link to an SQL database using EntityFramework.
There are two tables: Personnel and Role.
They are related with Personnel.RoleIdFk and Role.RoleId.
I am able to get a combobox to display the Role.RoleName for the associated RoleIdFk.
In my ViewModel:
private ICollection<Role> roleList;
public ICollection<Role> RoleList
{
get { return roleList; }
set { roleList = value; NotifyPropertyChanged("RoleList"); }
}
private Role selectedRole;
public Role SelectedRole
{
get { return selectedRole; }
set { selectedRole = value; NotifyPropertyChanged("SelectedRole"); }
}
public void SetSelectedRole()
{
if (SelectedPerson == null)
{
SelectedPerson = PersonnelList.Select(p => p)
.FirstOrDefault();
}
SelectedRole = RoleList.Where(p => p.RoleId == SelectedPerson.RoleIdFk)
.FirstOrDefault();
}
And the XAML for the ComboBox:
<ComboBox x:Name="cboRole"
Grid.Column="1" Grid.Row="0"
Width="150" Height="35"
ItemsSource="{Binding RoleList}"
DisplayMemberPath="RoleName"
SelectedItem="{Binding SelectedRole}"
/>
My problem is I am also displaying a DataGrid for the Personnel table.
In this DataGrid, I would like to have the associated RoleName displayed instead of the numerical foreign key.
The current XAML for the DataGrid:
<Window.DataContext>
<viewModel:MainWindowVM />
</Window.DataContext>
<ListView Name="lstPersonnel"
Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1"
ItemContainerStyle="{StaticResource ItemContStyle}"
ItemsSource="{Binding PersonnelList}" >
<ListView.View>
<GridView>
<GridViewColumn Width="75" Header="First Name" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FirstName}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="75" Header="Last Name" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding LastName}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="75" Header="Role" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding RoleIdFk}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
This is what the grid looks like:
For the final column, I have tried altering the text field in various ways.
I have also tried using other Templates and Styles. None of these have been successful.
Is there a way to actually perform this in XAML itself, or am I going to have to set up some sort of value converter to accomplish this?
NOTE: I had thought of using some sort of "switch/case" scenario. While it would work here, I need to figure out something that can be more dynamic. Later in the project I will need to associate the PersonnelId with other items. A "switch/case" scenario is not feasible with 300+ people.
"Role" should be available in "Personnel" object. So you can simply use "Role.RoleName" instead of "RoleIdFk":
<TextBlock Text="{Binding Role.RoleName}" />
In cases when you don't have a referenced object, it's better to join two collections and use a result as an ItemsSource of a DataGrid. Here is an example:
Joining two tables in one datagrid usig Linq C# WPF
There is also a solution with IMultiValueConverter, but it seems overcomplicated:
Joining 2 collections into datagrid using multibinding

WPF fill Listbox with collection member property

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>

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

Self Tracking Entities ListView Binding Losing Value On Change

My application is using Self-Tracking Entities & I get my data from a WCF Service. In my WCF service query I am using the .Include("") to load entity relationships with my query.
public List<IndividualDisability> GetIndividualDisabilities()
{
using (var context = new ADATrackingEntities())
{
return context.IndividualDisabilities.OfType<IndividualDisability>().Include("ADACode").ToList();
}
}
I'm then adding the results to an ICollectionView. I have a ListView that is bound to the ICollectionView, some of the columns in my ListView are bound to values from my entities relationship. I have a master-details setup with the current item of the listview bound to the entity object i'm editing.
<ListView Margin="0,0,10,0" MaxHeight="400" MaxWidth="300" HorizontalAlignment="Left" AlternationCount="2" ItemsSource="{Binding Path=IndividualDisabilitiesSource}" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding Path=CurrentIndividualDisability, Mode=TwoWay}" SelectionMode="Single" ItemContainerStyle="{DynamicResource ListViewItemContainerStyle}">
<ListView.View>
<GridView>
<GridViewColumn Header="Case #" Width="Auto"
DisplayMemberBinding="{Binding Individual.CaseNumberShort}" />
<GridViewColumn Header="LName" Width="Auto"
DisplayMemberBinding="{Binding Individual.LastName}" />
<GridViewColumn Header="FName" Width="Auto"
DisplayMemberBinding="{Binding Individual.FirstName}" />
<GridViewColumn Header="ADA Code" Width="Auto"
DisplayMemberBinding="{Binding ADACode.ADACodeDesc}" />
</GridView>
</ListView.View>
</ListView>
The problem is that on my edit section i'm using a combobox to change a value from the selected record and its changing the related value in my ListView to a blank value in the cell. The only way I can get it to show up again is by going back to the database and loading the data again. Is there something im missing with my combobox or listview binding??
<ComboBox Height="25" Width="200" ItemsSource="{Binding ADACodesSource}"
DisplayMemberPath="ADACodeDesc" SelectedValuePath="ADACodeID"
SelectedValue="{Binding Path=CurrentIndividualDisability.ADACodeID, Mode=TwoWay,
NotifyOnValidationError=True, ValidatesOnDataErrors=True}" />
I havent been able to get it working still with the combobox, so I settled for creating a custom control. Its an AutoComplete/ComboBox that seems to have the correct type of binding. Everything works great with this control detailed in this blog post:
http://weblogs.asp.net/dwahlin/archive/2009/07/06/creating-an-combobox-style-autocompletebox-control-in-silverlight.aspx

Categories