Can't show the DataTemplate on a selected item in combobox? - wpf

Newbie question. In the following combobox, the drop-down list correctly displays the company name and phone number as per the DataTemplate. However, selecting an item from the drop-down (by mouse) resutls only in showing the object name:
Stargate_V.DataService.View_Small_Company
The selected company name and phone number is not shown. What am I doing wrong?
<ComboBox
ItemsSource="{Binding PrimaryInsurance.Companies}"
ItemTemplate="{StaticResource CompanyTemplate}"
IsEditable="True"
IsTextSearchEnabled="True"
Height="20" HorizontalAlignment="Left" Margin="375,235,0,0" VerticalAlignment="Top" Width="198" />
The CompanyTemplate is:
<DataTemplate x:Key="CompanyTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Companyname}" Width="240"/>
<TextBlock Text="|" Width="10"/>
<TextBlock Text="{Binding Phone}" Width="80" />
</StackPanel>
</DataTemplate>
TIA

The issue that you are having is the combination of displaying a complex type (i.e. Class) with a DataTemplate and your ComboBox has IsEditable set to true. When setting IsEditable to true the ComboBox doesn't know which property to use for searching so it just calls ToString on the object and displays the results. To fix this issue you need to set the TextSearch.TextPath to the property name on the object that you would like to use for searching. Once you do that it will display that property in the selection box instead of the result of ToString. Below is what your XAML should look like if you wanted to search on the Companyname property on your object.
<ComboBox
ItemsSource="{Binding PrimaryInsurance.Companies}"
ItemTemplate="{StaticResource CompanyTemplate}"
IsEditable="True"
IsTextSearchEnabled="True"
TextSearch.TextPath="Companyname"
Height="20" HorizontalAlignment="Left" Margin="375,235,0,0" VerticalAlignment="Top" Width="198" />

Related

Link textbox to combobox - not working

I have a WPF usercontrol with a combobox & textbox. I want the textbox to hold the value of the selected item in the combobox and it works fine if I use SelectedValue in the binding path. However if I try to use the Title column of the combobox (SelectedValue.Title) the value of the textbox is overwritten but nothing is displayed. Can anyone tell me what I am doing wrong? My code sample is below. I am a newbie at this so please be kind :)
<ComboBox x:Name="ComboProject" Grid.Column="4" Grid.Row="0" TabIndex="14"
ItemsSource="{Binding Source={StaticResource Projects}, XPath=./Project}"
SelectedValuePath="#Item"
Tag="Project Number"
TextSearch.TextPath="#Item">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text= "{Binding XPath= #Item}" Width="90" />
<TextBlock Text= "{Binding XPath= #Title}" Width="220" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox x:Name="loaded" Text="{Binding Path=SelectedValue.Title, NotifyOnSourceUpdated=True, ElementName=ComboProject}" Grid.Row="2" Grid.Column="4" Tag="Project Title" TabIndex="15"/>
You set SelectedValuePath="#Item", so that's what SelectedValue has right now. Try setting it to Title and binding directly to SelectedValue:
<ComboBox x:Name="ComboProject"
ItemsSource="{Binding Source={StaticResource Projects}, XPath=./Project}"
SelectedValuePath="#Title">
<ComboBox.ItemTemplate>
...
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox Text="{Binding SelectedValue, ElementName=ComboProject}" />
I removed some other code for clarity of example.
EDIT :
Ok, if you want to use SelectedValue for other purposes we can bind TextBox to SelectedItem instead. If the Title is an attribute of a selected XML node, then we can access it like this:
<TextBox Text="{Binding SelectedItem.Attributes[Title].Value, Mode=OneWay, ElementName=ComboProject}" />

Binding ComboBox with one Item define and one dynamic

I have ComboBox with one define ComboBoxItem and one with TextBox as template.
Something like this:
<ComboBox Grid.Column="1" Grid.Row="4" Margin="3" VerticalAlignment="Center" SelectedItem="{Binding Repeatable}">
<ComboBoxItem Content="unbounded"/>
<ListBoxItem>
<ListBoxItem.Template>
<ControlTemplate>
<TextBox Text="{Binding Repeatable, Mode=TwoWay}" Width="200"/>
</ControlTemplate>
</ListBoxItem.Template>
</ListBoxItem>
</ComboBox>
My problem is that i don't know ho to bind a Repeatable string property.
If Repeatable = unbounded, I've need select ConboBoxItem and, if other string need fill text property of TextBox.
On click of any item in ComboBox, the value must be shown as selected.
Don't know ho to do that. Thanks for answers and ideas.
Try this:
<ComboBox Text="{Binding Repeatable}" IsEditable="True">
<ComboBoxItem Content="unbounded"/>
</ComboBox>

WPF - Filtering a DataCollection with an autocompletebox

I have a view and ViewModel that are working perfectly. I have recently added an AutocompleteBox (found in the WPF Toolkit) which allows users to quickly look up an item.
My view is as such:
An ItemsControl containing my CollectionViewSource named People. Generating perfectly
An AutocompleteBox where the dropdown shows only the items containing the values the user is typing in the AutocompleteBox. Works well. If I type John, all of the people in my CollectionViewSource named People with the word John in the name appear in the dropdown.
My issue is: how do I filter my ItemsControl when the user selects the item he wishes to see from the Dropdown?
My code so far in XAML to bind the data:
<toolkit:AutoCompleteBox Height="25" Width="400"
Foreground="AliceBlue"
ItemsSource="{Binding People.View}"
ValueMemberPath="Name"
Text="{Binding Name}"
IsTextCompletionEnabled="True"
FilterMode="Contains"
Background="#303030">
<toolkit:AutoCompleteBox.ItemTemplate>
<DataTemplate>
<Grid Width="360" HorizontalAlignment="Left">
<StackPanel Orientation="Vertical" HorizontalAlignment="Left"
VerticalAlignment="Top" Width="300">
<TextBlock Text="{Binding Name}" FontWeight="SemiBold" Foreground="#25A0DA"
FontSize="14" Width="300"/>
<TextBlock Text="{Binding Status}" FontWeight="Normal" Foreground="White"
FontSize="10" Width="300"/>
</StackPanel>
</Grid>
</DataTemplate>
</toolkit:AutoCompleteBox.ItemTemplate>
</toolkit:AutoCompleteBox>
<ItemsControl x:Name="tStack" Grid.Column="0" Grid.Row="1"
ItemsSource="{Binding People.View}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
BorderThickness="0.5">
</ItemsControl>
The itemsControl is styled and the format of the items inside it are also templated/styled but far too long and unconstructive to post here.
From the Name property setter in your viewmodel to which toolkit:AutoCompleteBox.Text is bound, you will have to filter the ObservableCollection backing your Collectionview i,e ItemsSource of your ItemsControl.
If you have your Collectionsource with you then you can have filter applied to it like below:
ICollectionView _peopleView = CollectionViewSource.GetDefaultView(peoples);
_peopleView .Filter = PeopleFilter
private bool PeopleFilter(object item)
{
People people= item as People;
return people.Name.Contains( _filterString ); //Here filter string will be your Name prperty value
}
From Setter of name property you will hav to call _peopleView .Refresh(); to apply the filter
Thanks

Multiselect ComboBox, Force it to always display the same text

I have a multiselect combobox that works fine. Except for the text. I want it to always have the same text ("Commodity Filter") regardless of what the user has selected.
If I set iseditable to true and the text to CommodityFilter it looks fine until the user makes a selection, then it is garbage (displays object type name). How can I hard code some text there? (Actually ideally i would databind it so it can change depending on whether anything is selected, but that would be a bonus at this point)
<ComboBox IsEditable="True" Text ="Commodity Filter" ItemsSource="{Binding Path=ActiveCommodities}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}"
Width="20" />
<TextBlock Text="{Binding Commodity}"
Width="100" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I ended up creating a custom object for populating the ComboBox (which had the IsSelected property and implemented INotifyPropertyChanged) because I was creating several comboboxes to control filtering. Once I did this is was trivial to override the tostring on the customobject and pass in the appropriate text. So the xaml did not change much.
I would have preferred to overlay with a text box but that seemed to be beyond my abilities to get a polished look in a reasonable time.
<ComboBox ItemsSource="{Binding Path=ActiveFuturesMonths}"
IsEditable="True"
IsReadOnly="True"
Text="Futures Month Filter" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}"
Width="20" />
<TextBlock Text="{Binding Text}"
Width="100" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Actually the crux is in setting -
IsEditable="True"
IsReadOnly="True"
Text="Futures Month Filter"
rather than creating custom object. thanks a lot it helped.

WPF DataGrid - Problem Customizing a ComboBox

I have a Datagrid with a combo box bound column that works great as follows:
<tk:DataGridComboBoxColumn SelectedValueBinding="{Binding DefaultLocationID}"
SelectedValuePath="LocationID"
DisplayMemberPath="LocationName"
Header="Default Location"
ItemsSource="{Binding Source={StaticResource CustomerLocations}}">
</tk:DataGridComboBoxColumn>
Ultimately I want to customize the dropdown to show 'ID' and 'Name' together so a TemplateColumn seems to be the way to go. Starting small, I can't get the following simple example to work which should replace the standard DataGridComboBoxColumn. The dropdown appears fine, but when I 'select' a dropdown item, it does not accept and goes back to the previous value. I've tried variations on 'Mode=TwoWay' but no luck. Do I need a 'CellEditingTemplate' ?
DefaultLocationID is the foreign-key field being edited, while 'LocationID' is a column in 'CustomerLocations'.
<tk:DataGridTemplateColumn Header="Default Location">
<tk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox VerticalAlignment="Top"
SelectedItem="{Binding LocationID, Mode=TwoWay}"
SelectedValue="{Binding DefaultLocationID, Mode=TwoWay}"
ItemsSource="{Binding Source={StaticResource CustomerLocations}}"
SelectedValuePath="LocationID"
DisplayMemberPath="LocationName" >
</ComboBox>
</DataTemplate>
</tk:DataGridTemplateColumn.CellTemplate>
Thanks!!
Can you post the relevant parts of your CustomerLocations resource? Can you also post the type of class that your grid is binding to?
Try removing the SelectedValuePath, DisplayMemberPath and SelectedValue from the ComboBox.
If you want to display multiple pieces of data in your combobox see the below XAML
<ComboBox ...>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding LocationId}"} />
<TextBlock Text=" - "/>
<TextBlock Text="{Binding LocationName}"} />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

Resources