How to get the checked items from combobox in wpf? - wpf

I have a combobox with checkbox and items, How do i select the particular item or multi item when checked in combobox.. Need help.. Below i tried code..
<UserControl.Resources>
<DataTemplate x:Key="cmbIndex">
<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Tag="{RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}"
Content="{Binding}"
Click="CheckBox_Click">
</CheckBox>
</DataTemplate>
<CollectionViewSource x:Key="coll" Source="{Binding CMDCollection}"/>
<UserControl.Resources>
<ComboBox Grid.Row="0"
HorizontalAlignment="Left" Margin="80,0,0,0"
SelectedItem="{Binding T3Command}"
Height="20" VerticalAlignment="Center" Width="60"
FontFamily="Calibri" FontSize="12">
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem>
<CheckBox x:Name="all">Select All</CheckBox>
</ComboBoxItem>
<CollectionContainer Collection="{Binding Source={StaticResource coll}}"/>
</CompositeCollection>
</ComboBox.ItemsSource>
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Name="chkTask" Content="{Binding}" IsChecked="{Binding ElementName=all, Path=IsChecked, Mode=OneWay}"></CheckBox>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemTemplate" Value="{StaticResource cmbIndex}"/>
</Style>
</ComboBox.Style>
</ComboBox>

1) Add a Bool type IsSelected property in your model. and bind that property to IsChecked property of Checkbox in Template.
2) Bind that property to ComboBoxItem's IsSelected in ItemContainerStyle.
you might want to come up with other solution to make Check All working(like converters).
this will work.

Related

ComboBox of CheckBoxes not checking item when row clicked

I've got a combo box of checkboxes that allow the user to select multiple temperature bands. When the users clicks on the checkbox, or the text directly next to the checkbox, the boxes are checked correctly, and my combobox text updates to add/remove the selected temperature. However if I check in the area of my combobox drop down to the right of the text, the checkbox isn't toggled, and instead I get namespace text in my combo box.
Here's my XAML
<ComboBox x:Name="cbDegrees" ItemsSource="{Binding m_DegreeValues}" Text="Degrees" IsEditable="True" IsReadOnly="True" Grid.Row="0" Grid.Column="0" Margin="5" Background="Gray" >
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Name="chkDegrees" Content="{Binding Name}" Checked="Degrees_CheckBox_Click" Unchecked="Degrees_CheckBox_Click" IsChecked="{Binding Path=IsSelected, Mode=TwoWay}">
</CheckBox>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I would like to have the checkbox toggled when I click anywhere in the line item for the temperature.
The default ComboBoxItem that is generated is not set to stretch and fill all available space. You can see this if you wrap your ComboBox in something like a DockPanel with it's Background property set.
<ComboBox.ItemTemplate>
<DataTemplate>
<DockPanel Background="CornflowerBlue">
<CheckBox Name="chkDegrees" Content="{Binding Name}" .. />
</DockPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
To fix it, set your ComboBoxItem style so it sets the HorizontalContentAlignment to Stretch
<ComboBox.Resources>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ComboBox.Resources>
You could define an ItemContainerStyle that makes the CheckBox stretch horizontally:
<ComboBox x:Name="cbDegrees" ItemsSource="{Binding m_DegreeValues}" Text="Degrees" IsEditable="True" IsReadOnly="True" Grid.Row="0" Grid.Column="0" Margin="5" Background="Gray" >
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ComboBox.ItemContainerStyle>
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Name="chkDegrees" Content="{Binding Name}" Checked="Degrees_CheckBox_Click" Unchecked="Degrees_CheckBox_Click" IsChecked="{Binding Path=IsSelected, Mode=TwoWay}">
</CheckBox>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

Change displayed text in XAML Combobox multi selection

I have the following code to allow users to select multiple items from a combobox. However when they click one item, it makes this the displayed text when combobox closes. Can I change the displayed text to something that isnt just the item selected. For example if the users select items A,B and D, I want the text part of the combobox to show "A, B, D"
<ComboBox ItemsSource="{Binding ListOfItems}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Width="20" />
<TextBlock Text="{Binding DisplayName}" Width="110" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Thanks
You could use a ContentControl with a Style that changes the ContentTemplate property for the selected item. The following sample markup should give you the idea.
<ComboBox ItemsSource="{Binding ListOfItems}">
<ComboBox.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<!-- the template for the items in the dropdown list -->
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Width="20" />
<TextBlock Text="{Binding DisplayName}" Width="110" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ComboBoxItem}}" Value="{x:Null}">
<Setter Property="ContentTemplate">
<Setter.Value>
<!-- the template for the selected item-->
<DataTemplate>
<ItemsControl ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource AncestorType=ComboBox}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}" Margin="0 0 5 0"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Please refer to the following similar question for more information.
Can I use a different Template for the selected item in a WPF ComboBox than for the items in the dropdown part?

How to add CheckBox content from resource file in wpf?

I have a combobox in which first item is checkbox to select all entries from below drop down list. With hard coded string its working fine but now I want to localize it...want to set string from resource file but as its deeply inserted couldn't add it. For that I tried adding panel and one checkbox along with textblock also simply separated textblock from checkbox.
This is code :
<ComboBox Name="CmbEntries" IsTabStop="{Binding CurrentDialogViewModel, Converter={StaticResource NullToBoolConverter}}" Grid.Column="1" Grid.Row="4" VerticalAlignment="Top" Margin="2,0,0,5" SelectedItem="{Binding SelectedEntries}" SelectedIndex="0" HorizontalAlignment="Left" Width="400">
<ComboBox.Resources>
<CollectionViewSource x:Key="EntriesCollection" Source="{Binding DicomDir.Entries}"/>
</ComboBox.Resources>
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem>
<CheckBox x:Name="all" Margin="8,0,0,0"
IsChecked="{Binding IsAllEntriessSelected, Mode=TwoWay}"
Command="{Binding SelectAllEntriessCommand}"
CommandParameter="{Binding IsChecked, RelativeSource={RelativeSource Self}}"
**Content="Select All Entries"** />
</ComboBoxItem>
<CollectionContainer Collection="{Binding Source={StaticResource EntriesCollection}}"/>
</CompositeCollection>
</ComboBox.ItemsSource>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Margin="8,0,0,0"
IsChecked="{ Binding Path=IsAnyEntitySelected, Mode=TwoWay }"
Command="{Binding SelectAllEntityCommand}"
CommandParameter="{Binding IsChecked, RelativeSource={RelativeSource Self}}" />
<TextBlock Margin="5,0,0,0" TextWrapping="Wrap" Text="{Binding DisplayEntriesInfo}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding HasSelectedEntities}" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
Scrshot1-Expected
Scrshot2-Actual with Resx
In this case, is it possible to read it directly from resource file?
To bind the content to a resource you do:
<Window ...
xmlns:properties="clr-namespace:YourNamespace.Properties">
<Grid>
<CheckBox Content="{x:Static properties:Resources.Foo}" />
</Grid>
</Window>
For this to work you need Resources to be public.
If it is not you get:
Provide value on 'System.Windows.Markup.StaticExtension' threw an exception...
StaticExtension value cannot be resolved to an enumeration, static field, or static property.

ComboBoxItem Will Not Collapse

I wrote a basic visibility converter such that when the property "Active" is true the ComboBoxItem should be Visible, Collapsed otherwise. It currently displays the Active ones properly, the inactive ones Text are invisible but the item can still be seen.
http://snag.gy/Mh2Xq.jpg
May I ask how do I get the ComboBoxItem to collapse the comboboxitem that are inactive properly please.
<ComboBox Grid.Row="1" Grid.Column="2" SelectedItem="{Binding Product, Mode=TwoWay}" ItemsSource="{Binding Products}" VerticalContentAlignment="Center">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="{Binding Active, Converter={StaticResource VisibilityConverter }}"></Setter>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Apply the visibility converter to the parent stackpanel instead. Like so:
<StackPanel Orientation="Horizontal" Visibility="{Binding Active, Converter={StaticResource VisibilityConverter}}">
...
</StackPanel>
<ComboBox.Resources>
<Style TargetType="ComboBoxItem">
<Setter Property="Visibility" Value="{Binding Active, Converter={StaticResource VisibilityConverter}}" />
</Style>
</ComboBox.Resources>
You should filter the bound list on basis of IsActive
Try to Bind comboBox to
Products.Where(t => t.IsActive)

Binding a checkbox in a datagrid header

I have a datagrid where the first column contains a checkbox to let the user selects specific rows. I have added a checkbox in the datagrid column header to check or uncheck all the rows.
Is it possible to add this functionality only with binding in XAML (no checked event).
<sdk:DataGrid AutoGenerateColumns="False" Grid.Row="1" Name="grid" ItemsSource="{Binding myCollection, Mode=TwoWay}" >
<sdk:DataGrid.Columns>
<sdk:DataGridCheckBoxColumn Binding="{Binding myCollection.UserSelected, Mode=TwoWay}" >
<sdk:DataGridCheckBoxColumn.HeaderStyle>
<Style TargetType="sdk:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox x:Name="checkAll" IsThreeState="True"
IsChecked="{Binding myCollection.UserSelected, Mode=TwoWay, Converter={StaticResource threeStateConverter}}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</sdk:DataGridCheckBoxColumn.HeaderStyle>
</sdk:DataGridCheckBoxColumn>
<sdk:DataGridTextColumn Binding="{Binding Description}" Header="Chemin" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
I think there's something wrong with the "myCollection.UserSelected" part. ThreeStateConverter is a value converter that would return null when some items are selected, true when they are all selected, etc. but the Convert method is never called (even though the PropertyChanged event is raised when UserSelected is changed).
Any idea on how I can do it? Thank you.
Probably, you've solved the problem already, but nevertheless:
<navigation:Page.Resources>
<model:MyModel x:Key="Model"/>
</navigation:Page.Resources>
...
<data:DataGridTemplateColumn Width="Auto" >
<data:DataGridTemplateColumn.HeaderStyle>
<Style TargetType="datap:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox IsThreeState="True" Margin="2,0,-13,0" DataContext="{StaticResource Model}" IsChecked="{Binding Path=AllChecked, Mode=TwoWay}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</data:DataGridTemplateColumn.HeaderStyle>
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Checked, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
MyModel class contains bool? property that implements logic of selection. It is also used as a `DataContext of page.
I must admit that this potentially has problems if we need to change model.
EDIT: I found another way:
<navigation:Page.DataContext>
<model:MyModel />
</navigation:Page.DataContext>
...
<data:DataGridTemplateColumn Width="Auto" >
<data:DataGridTemplateColumn.HeaderStyle>
<Style TargetType="datap:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox IsThreeState="True" Margin="2,0,-13,0" IsChecked="{Binding Path=DataContext.AllChecked, ElementName=LayoutRoot, Mode=TwoWay}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</data:DataGridTemplateColumn.HeaderStyle>
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Checked, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
Here we bind to DataContext of root layout element (usually called LayoutRoot) which inherits its data context from page by default.

Resources