AutoComboBox DisplayMemberPath call Converter or Set MultiBinding - wpf

In ComboBox ItemSource List Class set one Property that is Object of the class and I have to set in one for display purpose when I selectedItem
<AutoComboBox x:Name="cbPatient" Grid.Row="1" Grid.Column="3" ItemsSource="{Binding Path=Patients}"
SelectedItem="{Binding SelectedPatient}">
<AutoComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name,Converter={StaticResource NameToFullNameConverter}}"/>
</DataTemplate>
</control:AutoComboBox.ItemTemplate>
<control:AutoComboBox.DropDownView>
<GridView>
<GridViewColumn Header="Type" DisplayMemberBinding="{Binding Path=Name,Converter={StaticResource NameToFullNameConverter}}"/>
</GridView>
</control:AutoComboBox.DropDownView>
</control:AutoComboBox>
this converter works in DropDownView, but not work when I select an item from DropDownView
Thanks in advance

Related

WPF - Retrieve the object binded instead of a single property of the object

I have a checkbox and a textblock inside a stackpanel. When the textblock is clicked, the checkbox should be checked. Actually, it is a set of checkboxes and set of text blocks. Need to retrieve the value ID ( this is a property of the class "SomeClass" of the checkbox. But what has been binded to the Textblock is the name. My question is how do I retrieve the the whole object ?
<ListView>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<ItemsControl ItemSource="{Binding SomeClass} ">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox...../>
<TextBlock ...Text={Binding Name}/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView>
I am making use of the MouseLeftButton event of TextBlock. I can retrieve the Name, but what I need is the whole obect itself so that I can retrieve the ID property . Any solution to this ?
Use {Binding} without a property path or {Binding Path=.}

How to get selected item of a nested listview?

i have a nested listview, i can bind the selected item of the basic listview to my viewmodel but not my selected item of the nested listview ( in the basic listview ) I just do:
this is my listview:
<ListView Height="155" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible" dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="False" Margin="24,506,280,169" Background="#CDC5CBC5"
dd:DragDrop.DropHandler="{Binding}" SelectedItem ="{Binding Path=SelectedCluster,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" ItemsSource="{Binding Path=Clusters,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" >
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Titel" DisplayMemberBinding="{Binding Title}"/>
<GridViewColumn Header="Questions">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ListView DataContext="{Binding}" ItemsSource="{Binding ExaminationQuestions}" SelectedItem="{Binding Path=SelectedExaminationQuestionInCluster,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}">
<ListView.View>
<GridView>
<GridViewColumn Header="Description" DisplayMemberBinding="{Binding Question.Description}"/>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
Viewmodel:
public ExaminationQuestion SelectedExaminationQuestionInCluster
{
get { return selectedExaminationQuestionInCluster; }
set { selectedExaminationQuestionInCluster = value;
OnPropertyChanged("SelectedExaminationQuestionInCluster");
}
}
Someone who knows what i am doing wrong? If i set a breakpoint of the setter of selecteditem of the second listview. He just ignores that..
Thanks
My guess is the binding is probably incorrect. In your outer ListView, you bind to "Clusters". Your inner ListView is probably trying to bind to "SelectedExaminationQuestionInCluster" on the current Cluster. You can see if this is the case by using snoop. It's a valuable tool when debugging WPF apps. It will highlight broken bindings in red and tell you what's wrong with them.
If you want to bind to "SelectedExaminationQuestionInCluster" on the parent DataContext, you could use this syntax:
SelectedItem="{Binding Path=DataContext.SelectedExaminationQuestionInCluster,
ElementName=OuterListView}"
You'll have to give the outer ListView a name of course.
EDIT: I just realized this might not make sense. If each Cluster has its own collection of ExaminationQuestions, then each Cluster should also have a SelectedExaminationQuestion. The parent DataContext should not have any concept of a SelectedQuestion unless it is shared amongst all Clusters.

binding combox in wpf datagrid

I have a list that I populate in the init of my viewmodel:
ListOfEmployees = new List<EmployeeBO>(employeeRepository.GetEmployees(true, true));
I am trying to get a combobox in a datagrid to populate from this list.
<DataGridTemplateColumn Header="U/M" MinWidth="145">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Name="cboUnitMeasure"
ItemsSource="{Binding Path=ListOfUnitMeasures}"
DisplayMemberPath="UnitMeasureDescription" SelectedValuePath="UnitMeasureValue"
SelectedValue="{Binding UnitMeasureValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left" Width="140" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding UnitMeasureDescription}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
When the dg loads, the cell template displays the UnitMeasureDescription value, but when I click on the cell to edit, there are no items in the combobox. On the other hand, when I use a static resource from an xml file as the itemsource-using the same property names-the combobox contains the items:
<DataGridTemplateColumn Header="U/M" MinWidth="145">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Name="cboUnitMeasure"
ItemsSource="{Binding Source={StaticResource UnitMeasureData}}"
DisplayMemberPath="UnitMeasureDescription" SelectedValuePath="UnitMeasureValue"
SelectedValue="{Binding UnitMeasureValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left" Width="140" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding UnitMeasureDescription}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I put a breakpoint just after populating ListOfEmployees in my vm and it contains items. I also verified the property names in the DisplayMemberPath and SelectedValuePath are correct. Not sure what I am doing wrong here.
Is "ListOfUnitMeasures" a property on the VM or a property of an EmployeeBO? Ok, assuming that the DataGrid's ItemsSource is set to the List<EmployeeBO> and that there's another list on the VM called "ListUnitOfMeasures", here's my explanation:
The DataContext of each row in the DataGrid will be equal to the elements in the DataGrid's ItemsSource. In your case, each row will use an EmployeeBO as its DataContext. And since the "ListOfUnitMeasures" isn't a property of Employee BO, the Binding on the ComboBox will not work and thus won't display anything.
One possible solution is change the Binding on your ComboBox to use a RelativeSource pointing back to the parent DataGrid as follows:
<ComboBox Name="cboUnitMeasure"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.ListOfUnitMeasures}"/>

How to fetch all the rows in a listview wpf

I have a list view which has a grid view with four columns. The itemsSource for the listview is an IList(Of SomeType). Each cell in the grid contains a checkboxes, which are checked/unchecked based on the values in the bound property. Now i want to retrieve all the rows in list/grid view for saving purposes or atleast all those checkboxes that are checked. I couldn't find a suitable way to do that.
Here is how i create my listview.
<ListView Margin="10, 40, 95, 10" x:Name="ListViewPane">
<ListView.View>
<GridView x:Name="gridColumns">
<GridViewColumn Width="auto" Header="Right" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Width="auto" Header="Read">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="0" VerticalAlignment="Center" IsChecked="{Binding CanRead}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="auto" Header="Write">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="0" VerticalAlignment="Center" IsChecked="{Binding CanWrite}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="auto" Header="Delete">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="0" VerticalAlignment="Center" IsChecked="{Binding CanDelete}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Can anyone help me????
You can iterate through the Items object of the ListView to get the values:
foreach( var item in this.ListViewPane.Items )
{
var ofSomeType = item as OfSomeType;
if( ofSomeType != null )
{
string name = ofSomeType.Name;
bool canDelete = ofSomeType.CanDelete;
bool canRead = ofSomeType.CanRead;
bool canWrite = ofSomeType.CanWrite;
// do stuff with your Of Some Type objects
}
}
You need to set the IsChecked Bindings to Mode=TwoWay, e.g.
IsChecked="{Binding CanRead, Mode=TwoWay}"
Then WPF will update your business objects as the user checks and unchecks the boxes.
Now you can just collect the values directly from your business object collection (the ItemsSource):
For Each busobj In ListViewPane.ItemsSource
If busobj.CanDelete Then
' whatever
End If
Next
(pardon any syntax errors in the VB)
If you really need to access the ListViewItem controls that represent the physical rows in the UI control, you can get at them using the ItemContainerGenerator:
For Each busobj In ListViewPane.ItemsSource
Dim lvi As ListViewItem = CType(ListViewPane.ItemContainerGenerator.ContainerFromItem(busobj), ListViewItem)
Next

How can I display different ContextMenus in WPF ListView GridView?

I have a ListView GridView with ListViewItems that represent different categories of items. I'd like to display a different ContextMenu for each category of item. I was hoping to do this using DataTemplates but I'm struggling. My TreeView has a DataTemplate per category and I can see how I can set a different ContextMenu for each there but I can't seem to get similar DataTemplates to work for my ListView. Am I barking up the wrong tree?
E.g. this is one of my DataTemplates for the TreeView:
<DataTemplate DataType="{x:Type viewModel:Cat1ViewModel}">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Margin="3,0"
Source="..\Images\cat1.png"/>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
and I can add my ContextMenu to the StackPanel (I hope) and Bob's my uncle.
But the guts of the GridView looks like this:
<ListView.Resources>
<DataTemplate x:Key="image">
<Image Width="16" Height="16" Margin="-3,0,-3,0"
HorizontalAlignment="Center"
Source="{Binding Path=ObjectClass,
Converter={StaticResource imageConverter}}" />
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Width="20"
CellTemplate="{StaticResource image}"/>
<GridViewColumn Width="140" Header="Name"
DisplayMemberBinding="{Binding Path=Name}"
infrastructure:GridViewSort.PropertyName="Name"/>
<GridViewColumn Width="140" Header="Type"
DisplayMemberBinding="{Binding Path=Category}"
infrastructure:GridViewSort.PropertyName="Category"/>
<GridViewColumn Width="400" Header="Description"
DisplayMemberBinding="{Binding Path=Description}"
infrastructure:GridViewSort.PropertyName="Description"/>
</GridView>
</ListView.View>
This imageConverter in the DataTemplate resource displays the appropriate icon for the category of the listViewItem.
I'm not sure where to start. So, first, is what I want to do possible? If so, can you get me started, please.
Also:
At the moment, each ListViewItem is backed by a viewModel - all categories use the same viewModel class.
Background:
The reason I want to display a different ContextMenu rather than changing the ContextMenu is that I'm using Prism and the ContextMenus will be Regions populated automatically by various modules.
I think you can do this with an ItemTemplateSelector, rather than setting the ItemTemplate property on your ListView, use the ItemTemplateSelector property. You have to create your own implementation of the ItemTemplateSelector class and define the logic so that it knows which template to use for each set of conditions, then you just need to create a set of templates and you should be good to go! There's a good tutorial on how to do this here.

Resources