Telerik RadComboBox ItemTemplate and MultipleSelectionBoxTemplate - c#

how can i specify MultipleSelectionBoxTemplate which i can access properties of selected items
i have an employee class
public class Employee {
public string Firstname {get;set;}
public string Lastname {get;set;}
}
I am using Telerik radCombobox in my wpf application to display list of employee
<telerik:RadComboBox x:Name="radComboBox"
Width="200"
AllowMultipleSelection="True"
ItemsSource="{Binding Path=EmployeeList}"
>
<telerik:RadComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Lastname}" />
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
this works fine for itemtemplate but when i select an item the display text in combobox show name of Employee class not the Lastname
i tried
<telerik:RadComboBox.MultipleSelectionBoxTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Lastname}" />
</DataTemplate>
</telerik:RadComboBox.MultipleSelectionBoxTemplate>
i get no result , the combobox displayvalue of selected item is always empty.
i tried another solution
<telerik:RadComboBox.MultipleSelectionBoxTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=SelectedItems,Converter={StaticResource SelectionToCustomStringCoverter}}" />
</DataTemplate>
</telerik:RadComboBox.MultipleSelectionBoxTemplate>
this neither work , the converter always execute at first selection
this is really crazy spending 4 hours to figure out a simple thing ,
so my question is how can i specify MultipleSelectionBoxTemplate which i can access properties of selected items .

this neither work , the converter always execute at first selection
You need to bind to a property that is actually set when the selection changes, such as the Count property of the SelectedItems collection.
Try using a multi value converter and a MultiBinding:
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource SelectionToCustomStringCoverter}">
<Binding Path="SelectedItems" RelativeSource="{RelativeSource AncestorType=telerik:RadComboBox}"/>
<Binding Path="SelectedItems.Count" RelativeSource="{RelativeSource AncestorType=telerik:RadComboBox}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
You will then get the currently selected items from values[0] in the converter.

Related

MVVM Binding one ComboBox from another

I am pretty new into MVVM and I wanted to ask, if you could help me getting the SelectedValue from a ComboBox to my VM-Class. In my example I have a ComboBox with all the car brands. If I select a car brand I want to have all the models from the car brand in another ComboBox to choose from. I've already made some research but I couldnt find a single solution to my problem.
After clicking on the Brand-ComboBox.
This is fine so far, but when I want to have the models displayed, the ComboBox stays empty.
Code from my View-Class:`
<ObjectDataProvider x:Key="vmcars" ObjectType="{x:Type local:VMCars}"/>
<!--MainGrid-->
<Grid DataContext="{StaticResource vmcars}">
.
.
.
.
</Grid>
Code from my Brand-ComboBox:
<!--CarBrand Combobox-->
<ComboBox x:Name="carBrand" Style="{StaticResource combobox}"
ItemsSource="{Binding AllCars}"
Grid.Column="1" Grid.Row="1"
DisplayMemberPath="c_brand"
Margin="20,13,17,15"
VerticalAlignment="Center" Height="30">
<ComboBox.SelectedItem>
<Binding Path="SelectedBrand"
BindsDirectlyToSource="True"
Mode="OneWayToSource" />
</ComboBox.SelectedItem>
</ComboBox>
Code from my Model-ComboBox:
<!--CarModel ComboBox-->
<ComboBox x:Name="carModel" Style="{StaticResource combobox}" Grid.Column="1"
Margin="20,15,17,14"
ItemsSource="{Binding ModelSelectedBrand}" DisplayMemberPath="c_model"
Grid.Row="2" VerticalAlignment="Center" Height="30">
</ComboBox>
Code from my VMClass:
public string selectedBrand;
public string SelectedBrand
{
get { return selectedBrand; }
set
{
selectedBrand = value;
PropertyChanged(this, new PropertyChangedEventArgs
("ModelSelectedBrand"));
}
}
public IEnumerable<c_car> ModelSelectedBrand
{
get
{
return (from c in db.c_car
where c.c_brand.Equals(SelectedBrand) //THIS IS CAUSING PROBLEMS
select c).GroupBy(x=>x.c_model).Select(x=>x.FirstOrDefault()).OrderBy(x=>x.c_model).ToList();
}
}
When I then comment the WHERE clause in my Linq statement, I get this result:
click here
These are all the car models.
I think the problem is that my "SelectedBrand" Property doesnt get any value from the carBrand-ComboBox
Therefore, I wanted to ask you, if anybody has an idea what might cause the trouble.
Your car brand ComboBox is currently passing the class name of c.car to your query. If you bind to SelectedValue instead of SelectedItem, and set SelectedValuePath to "c_car" it works.
So your new CarBrand ComboBox definition will be
<!--CarBrand Combobox-->
<ComboBox x:Name="carBrand" Style="{StaticResource combobox}"
ItemsSource="{Binding AllCars}"
Grid.Column="1" Grid.Row="1"
DisplayMemberPath="c_brand"
SelectedValuePath="c_brand"
Margin="20,13,17,15"
VerticalAlignment="Center" Height="30">
<ComboBox.SelectedValue>
<Binding Path="SelectedBrand"
BindsDirectlyToSource="True"
Mode="OneWayToSource" />
</ComboBox.SelectedValue>
</ComboBox>

Updating the source of a Listbox with a multibinding

I'm trying to get a multi-bound listbox to call the convert back method when items inside it change. Specifically I have a datatemplate that maps each entry to a checkbox and I'd like the source to be updated whenever a box is checked.
<ListBox x:Name="listBoxEdit" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="100" >
<ListBox.ItemsSource>
<MultiBinding Converter="{StaticResource selectedLoadsConverter}" >
<Binding Path="AvailableLoads"/>
<Binding Path="CurrentUnit"/>
</MultiBinding>
</ListBox.ItemsSource>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Item1}" IsChecked="{Binding Item2}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I know the problem lies in the fact that I'm binding to to the ItemsSource property which is never actually being updated by the checkbox changing, but I can't figure out a good way to push the updates up to the source.

ComboBox.ItemTemplate not displaying selection properly

In the question c# wpf - cannot set both DisplayMemberPath and ItemTemplate, I have read that you can replace the DisplayMemberPath to combine multiple data items in a ComboBox.
I set up my Combobox using ItemTemplate and it is successfully populated. But when I select an item in my ComboBox, I get Data.MaterialNumber displayed instead of the actual text I selected.
MaterialNumbers is an ObservableCollection<>
Can someone tell me why my ComboBox is not displaying the item correctly after it is selected?
// Binding from my ViewModel, which retrieves material numbers correctly.
ObservableCollection<MaterialNumber> MaterialNumbers = GetMaterialNumbers();
<ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding MaterialNumbers}"
SelectedItem="{Binding MaterialNumber}"
Validation.Error="View_Validator" Validation.ErrorTemplate="{StaticResource ErrorTemplateBorder}"
IsEnabled="{Binding IsEnabled}" IsEditable="True" IsReadOnly="True" Margin="0,10,0,0">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}: {1}">
<Binding Path="Program.Name" />
<Binding Path="MaterialNumberString" />
<Binding UpdateSourceTrigger="PropertyChanged" />
<Binding NotifyOnValidationError="True" />
<Binding ValidatesOnDataErrors="True" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Thanks to this article http://www.shujaat.net/2010/08/wpf-editable-combobox-with-datatemplate.html, I was able to figure out why my ComboBox did not display correctly when an item was selected. It is because my ComboBox was set to IsEditable="True". Apparently, when using a ComboBox.ItemTemplate and having MultiBinding set, the ComboBox cannot determine which item to display so it displays the class instead.

Show multiple columns from database in one combobox

I want to show in one combobox content from two database columns. I would like to show "Name Surname" but I don't know how. I'm working in C# (.NET) using MVVM pattern. "Name" and "Surname" are fields from table "tblGuests".
Thanks in advance,
Vladimir
You could create an ItemTemplate for the ComboBox that binds to all the properties you want to show.
<ComboBox ItemsSource="{Binding}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=FirstName}" Padding="10,0,0,0"/>
<TextBlock Text="{Binding Path=LastName}" Padding="10,0,0,0"/>
</StackPanel>
<DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
You could even create a UserControl that can be re-used and use that:
<PersonView>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=FirstName}" Padding="10,0,0,0"/>
<TextBlock Text="{Binding Path=LastName}" Padding="10,0,0,0"/>
</StackPanel>
</PersonView>
<ComboBox ItemsSource="{Binding}">
<ComboBox.ItemTemplate>
<DataTemplate>
<PersonView/>
<DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Keep a string list property in Viewmodel,
populate that property in a data loading method, by combining name and surname strings,
bind string property to combo box,
<ComboBox Name="ComboBox1" ItemsSource="{Binding YourStringListProperty}"/>
Another option could be to use MultiBinding something like this
<TextBlock Name="textBox2" DataContext="{StaticResource NameListData}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource myNameConverter}"
ConverterParameter="FormatLastFirst">
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
This code was taken directly from msdn. Refer to it for more details

Compound DisplayMemberPath for a combobox

I need to create a DisplayMemberPath that is a compound of a few properties (ie object.category.Name+" -> "+object.description) I'm pretty sure I can do this by creating a dynamic data type that encapsulates the object and also adds a new property called displayField that is what I need but I'm wondering if there is a more proper way to do this that does not involve creating a new object. Any ideas?
DisplayMemberPath is just a "shortcut" for when you don't need a complex template for items. If you need more control, use ItemTemplate instead:
<ComboBox ItemsSource="{Binding Items}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} -> {1}">
<Binding Path="Category.Name" />
<Binding Path="Description" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

Categories