wpf Combobox Itemssource not binding within Listbox Data Template - wpf

Please help to fix the below issue.
I have Combobox inside listbox item datatemplate so that I can load multiple combobox but same itemsource
<StackPanel>
<ListBox Width="400" Name="lstFiles" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Name="dataGrid">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Name="dragFileName"
Margin="5,0,0,0"
Text="{Binding fileName, UpdateSourceTrigger=Default}" />
<ComboBox Grid.Row="0"
Grid.Column="1"
Margin="5,0,0,0"
Name="cboDragDocType"
ItemsSource="{Binding dragDocType, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"
Text="{Binding dragDocTypeText}"
IsEditable="True"
IsReadOnly="True" />
<Button Name="dragDelBtn"
Grid.Column="2"
Height="20">X</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
Data is loading in comboBox by using ObservableCollection property. In Initialize method i do for loop method to get multiple items.
Problem scenario: Select item from the dropdown1 --> then Select item from the dropdown2 -->Again click dropdown1, Now dropdown1 itemssource is empty.

You don't have a binding to the SelectedItem (or SelectedValue) property of the ComboBox. Therefore the value cannot be saved (or retrieved).
You need to add a property in your class that acts as the DataContext to hold the selected item of the ComboBox, for example:
<ComboBox Grid.Row="0"
...
SelectedItem="{Binding Path=SelectedDragDocType, UpdateSourceTrigger=LostFocus}" />
As a side-note having both IsEditable and IsReadOnly properties on the ComboBox set to true is pretty restrictive. Are you sure it is the intended behavior?

Related

How can I set the binding for a control's property (which is inside DataTemplate and UserControl) to use the ItemSource's given property?

I would like to make a UserControl which have a DataTemplate, and inside that DataTemplate there are controls. I would like to bind to those nested (inside the DataTemplate) controls' properties so I can set them when I reuse this UserControl. The nested controls will use the ItemSource's properties but the property names of the ItemSource's properties could be different.
The UserControl:
<UserControl x:Class="ContextMenu.BaseFilterUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Name="Self">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="70" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="10"
Text="Owners" />
<Button Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="10"
Click="FilteButtonClicked"
Width="40"
Height="40"
x:Name="FilterButton">
<Popup x:Name="FilterBoxPopup"
PlacementTarget="{Binding ElementName=FilterButton}"
Placement="Bottom"
StaysOpen="False">
<Border BorderBrush="Black"
Background="White"
Margin="2">
<ListView ItemsSource="{Binding ElementName=Self, Path=FilterList}"
x:Name="FilterListView"
Height="300"
Width="150">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!--<CheckBox IsChecked="{Binding IsChecked}" />-->
<!--<TextBlock Text="{Binding Name}" />-->
<!--This is where I don't know how to properly bind eg. the above control, things I tried:-->
<!--<TextBlock Text="{Binding ElementName=FilterListView, Path=FilterElementName}" />-->
<!--<TextBlock Text="{Binding ElementName=Self, Path=DataContext.FilterElementName}" />-->
<!--<TextBlock Text="{Binding ElementName=FilterListView, Path=DataContext.FilterElementName}" />-->
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Border>
</Popup>
</Button>
<TextBlock Grid.Column="3"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10"
Text="{Binding ElementName=Self, Path=SelectedNames}" />
</Grid>
</UserControl>
This how the UserControl is used, the FilterElementName="Name" is what I would like to set, depending on the list binded with FilterList list:
<local:BaseFilterUserControl FilterList="{Binding Owners}"
FilterElementName="Name"
SelectedNames="{Binding SelectedNames}"/>
In this case the Owners is a simple IReadOnlyList of an Owner class. The Owner class has a string Name property. But I will use this UserControl again with different list eg. where I would like to use the Versions list's Release property (for the TextBlock inside the UserControl):
<local:BaseFilterUserControl FilterList="{Binding Versions}"
FilterElementName="Release"
SelectedNames="{Binding SelectedReleases}"/>
The ListView is properly populated with items, so the FilterList DependencyProperty is working. But the nested controls are only working when I hard code the bindings:
<TextBlock Text="{Binding Name}" />
For this to work you would need to bind the Path-property of your TextBlocks Text-Binding to the FilterElementName property of your UserControl. Unfortunately the Path property of the Binding class is not a DependencyProperty and therefore not bindable.
One way to to achieve your goal would be to use the DisplayMemberPath property of the ListView, which is bindable:
<ListView x:Name="FilterListView"
Width="150"
Height="300"
ItemsSource="{Binding ElementName=Self, Path=FilterList}"
DisplayMemberPath="{Binding ElementName=self, Path=FilterElementName}"/>
If this approach does not work because you need to specify a more complex ItemTemplate, another way would be create a property of type DataTemplate in your UserControl, use that as ItemTemplate in the ListView and specify it from outside like so:
<local:BaseFilterUserControl FilterList="{Binding Versions}"
SelectedNames="{Binding SelectedReleases}">
<local:BaseFilterUserControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Release}" />
</DataTemplate>
</local:BaseFilterUserControl.ItemTemplate>
</local:BaseFilterUserControl>

Display items in dropdown list and selected items box via the same binding using only XAML

I'm sure that someone will jump all over this as being answered somewhere else but I claim I have followed every relevant link on this site (and elsewhere) and tried all possible combinations of ItemTemplate, ComboBoxItem, ItemContainerStyle, DisplayMemberPath, SelectedItem, SelectedValuePath and SelectedValue and for the life of me I can't get this to work as desired.
I simply want to define a list of ContentControl object (using x:Array) in XAML resources used as an ItemsSource for a ComboBox. This list contains 2 elements whose Content property is set to a Grid control - also defined in the resources. Each item also has the Tag property set to a string that functions as the name or description of the content.
Very simply: I want the string in the Tag property to be displayed in the selected item portion of the ComboBox and as the list of selectable items in the dropdown portion of the ComboBox.
If I set DisplayMemberPath="Tag", then the dropdown portion works as desired but nothing is displayed in the selected item portion of the ComboBox. I'm sure that proper use of SelectedValuePath and SelectedValue is the key, but I simply can't get it to work.
<UserControl.Resources>
<Grid x:Key="Fluidics" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="134"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Content="Cartridge:"
VerticalAlignment="Center" HorizontalAlignment="Left"
Margin="0,5,0,0" Height="26" Width="62"/>
<ComboBox Grid.Column="1"
ItemsSource="{Binding Cartridges}"
SelectedIndex="{Binding SelectedCartridgeIndex, FallbackValue=0}"
SelectedItem="{Binding SelectedCartridge}"
Margin="0,5,0,0" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Config.FriendlyName}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<views:FluidicsExperimentParamsView Grid.Row="1" Grid.ColumnSpan="2" DataContext="{Binding FluidicsExperimentParams}" Margin="0,10,0,0"/>
</Grid>
<Grid x:Key="Data acquisition" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="157"/>
<ColumnDefinition Width="Auto" MinWidth="87"/>
</Grid.ColumnDefinitions>
<Label Content="Camera line:" />
<ComboBox
Grid.Column="1"
IsReadOnly="True"
ItemsSource="{Binding ImageDataAcquisitionParams}"
SelectedIndex="{Binding SelectedCameraLine}"
SelectedItem="{Binding SelectedImageDataAcquisitionParams}"/>
<data:ImageDataAcquisitionView
Grid.Row="1"
Grid.ColumnSpan="2"
DataContext="{Binding ImageDataAcquisition}" Margin="0,10,0,0"/>
</Grid>
<x:Array x:Key="ControlActivities" Type="ContentControl">
<ContentControl Content="{Binding Source={StaticResource Fluidics}}" Tag="Fluidics" />
<ContentControl Content="{Binding Source={StaticResource Data acquisition}}" Tag="Data acquisition"/>
</x:Array>
</UserControl.Resources>
...
<ComboBox Name="ControlActivityComboBox"
MinWidth="150"
ItemsSource="{Binding Source={StaticResource ControlActivities}}"
SelectedItem="{Binding SelectedActivity}"
SelectedValuePath="Tag"
SelectedValue="{Binding SelectedActivity.Tag}"
DisplayMemberPath="Tag"
HorizontalAlignment="Left"
SelectedIndex="0">
</ComboBox>

Radcombobox loses value when clicked on another control

Two comboboxes - the user makes a selection in the first which provides a default value for the 2nd. This works well until a series of keystrokes happen. If the 2nd gets the focus, but not changed, then the first gets the focus, the default value disappears for the 2nd.
What would cause the default value disappear?
I suspect the second combo is not set up correctly but I'm not sure how to fix it.
<telerik:RadComboBox x:Name="cboGlaze" FontSize="16" Background="#F6F8FA" BorderBrush="#D7D8DD"
ItemsSource="{Binding}"
Text="{Binding glaze, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
telerik:TextSearch.TextPath="Glaze"
IsEditable="True" IsReadOnly="True"
Style="{DynamicResource RadComboBoxStyle3}" >
<telerik:RadComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Glaze}"></TextBlock>
<TextBlock Text="{Binding pctUpcharge}" Grid.Column="1"></TextBlock>
</Grid>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
Binding to the property "glaze" is handled in the DropDown event for the first combo.
Thanks for any help or advice.
Try to bind the SelectedValue property of the RadComboBox to the glaze source property and set the SelectedValuePath property to "Glaze" provided that the DataTable contains a column with this name:
<telerik:RadComboBox x:Name="cboGlaze" FontSize="16" Background="#F6F8FA" BorderBrush="#D7D8DD"
ItemsSource="{Binding}"
SelectedValuePath="Glaze"
SelectedValue="{Binding glaze}"
telerik:TextSearch.TextPath="Glaze"
IsEditable="True" IsReadOnly="True"
Style="{DynamicResource RadComboBoxStyle3}" >
...

Retrieving selected item from listbox

How do i retrieve values from selected item in listbox.
I have a databound listbox:
<ListBox x:Name="EventsListBox"
ItemsSource="{Binding}"
SelectedValuePath="idevents"
ItemTemplate="{DynamicResource DataTemplate2}"
/>
Which uses this datatemplate to populate:
<DataTemplate x:Key="DataTemplate2">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Margin="0,5,5,5" Grid.ColumnSpan="2">
<DockPanel TextBlock.FontWeight="Bold" >
<TextBlock Text="{Binding Path=eventname, FallbackValue=Manchester}" HorizontalAlignment="Center"/>
</DockPanel>
<TextBlock Text="{Binding Path=realchannelname, FallbackValue=Channel}" FontStyle="Italic" HorizontalAlignment="Left" />
<TextBlock Text="{Binding Path=datetime, FallbackValue=datetime}" HorizontalAlignment="Left" />
</StackPanel>
</Grid>
</DataTemplate>
How would i get 'eventname' value and set it as a string to a label here;
Private Sub EventsListBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles EventsListBox.SelectionChanged
End Sub
In general, I try to do things through binding because they will automatically update.
In Code Behind you can gain access to the value of the item via the SelectedValue property.
String value = EventsListBox.SelectedValue;
A better way of doing this is to have a binding update a property. This way everything always will update with bindings
<ListBox x:Name="EventsListBox"
SelectedValue="{Binding SelectedEventName} >
</ListBox>
You should note that the SelectedEventName is a property on the viewmodel that the listbox is bound to.

How to get selected item value?

How to get ItemsControl display items selected Item textbox text value using MVVM pattern?
<ListBox Margin="0,25,0,0" Grid.Row="3" ItemsSource="{Binding Path=ViewModelSearchResults}" SelectedItem="{Binding Path=SelectedCategoryViewModel, Mode=TwoWay}">
<ItemsControl.ItemTemplate>
<DataTemplate >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" Text="{Binding Path=CategoryName}" FontSize="14" FontWeight="Normal" />
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=CategoryID}" FontSize="14" FontWeight="Normal" Visibility="Hidden" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
Like getting anything else from Views: bind it! Yes, ItemsControl has SelectedItem but ItemsControl itself doesn't have selection behavior. You should use something like ListBox instead.
You can bind SelectedItem to a property and access the required values through that property.

Resources