This question already has answers here:
How to stretch checkbox item the full width of the combobox
(3 answers)
Closed 4 years ago.
I have checkboxes inside of a Combobox and I want to click them:
If I click the Checkbox or the "Content" of the Checkbox it will check the Checkbox, but if I click on empty space right next to the "content", it will just select this Checkbox in the Combobox.
How can I prevent that? I want to check the box if I click on the whole field, not just on the text alone.
Here is my Code:
<ComboBox Margin="2,2,2,0" ItemsSource="{Binding DataContext.AllTags, ElementName=self}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Name}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding DataContext.CmdCmx_UpdateTags, ElementName=self}" CommandParameter="{Binding}" />
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding DataContext.CmdCmx_UpdateTags, ElementName=self}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</ComboBox.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="DropDownOpened">
<i:InvokeCommandAction Command="{Binding DataContext.CmdCmx_ClearTags, ElementName=self}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
Add an ItemContainerStyle that sets the HorizontalContentAlignment property of the ComboBoxItem containers to Stretch:
<ComboBox Margin="2,2,2,0" ItemsSource="{Binding DataContext.AllTags, ElementName=self}" >
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ComboBox.ItemContainerStyle>
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Content="Name">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding DataContext.CmdCmx_UpdateTags, ElementName=self}" CommandParameter="{Binding}" />
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding DataContext.CmdCmx_UpdateTags, ElementName=self}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</ComboBox.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="DropDownOpened">
<i:InvokeCommandAction Command="{Binding DataContext.CmdCmx_ClearTags, ElementName=self}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
Related
Hello i'm doing a simple program that loads a picture and adds a rectangle to the canvas.
i have this xaml code
<Grid>
<Image x:Name="img" Source="{Binding ImagePath, Source={x:Static vm:DrawingVM.instance}, Converter={StaticResource nullImageConverter}}" Stretch="None">
</Image>
<ItemsControl ItemsSource="{Binding ListRectangle, Source={x:Static vm:DrawingVM.instance}}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="cnvas" Width="{Binding ElementName=img, Path=ActualWidth}"
Height="{Binding ElementName=img,Path=ActualHeight}"
LayoutTransform="{Binding ElementName=img, Path=LayoutTransform}">
<!--MouseDown="cnvas_MouseDown" MouseLeftButtonDown="cnvas_MouseLeftButtonDown"-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<ei:CallMethodAction MethodName="MouseDownDrawing" TargetObject="{Binding Source={x:Static vm:ResizerVM.instance}}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<ei:CallMethodAction MethodName="MouseMoveDrawing" TargetObject="{Binding Source={x:Static vm:ResizerVM.instance}}" />
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown" >
<ei:CallMethodAction MethodName="OnLeftButtonClicked" TargetObject="{Binding Source={x:Static vm:ResizerVM.instance}}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonDown" >
<ei:CallMethodAction MethodName="MouseLeftButtonDownClicked" TargetObject="{Binding Source={x:Static vm:ResizerVM.instance}}" />
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp" >
<ei:CallMethodAction MethodName="DragFinishedMouseHandler" TargetObject="{Binding Source={x:Static vm:ResizerVM.instance}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="Blue" Fill="Transparent" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
What i'm trying to do is to draw a rectangle in the canvas but mouse. but it doesn't execute the event because the Image is UPPER. how can i set the position of the IMAGE so that the CANVAS is UPPER? so i can execute the event like drawing a rectangle using mouse
If an item appears as a later child of a grid, it should be on top of previous elements and therefore should be getting input. However, if there is another item stealing input, you can set IsHitTestVisible="False" on the item and it should no longer be clickable.
If the Image doesn't turn out the be the element that's causing the problem, you might want to check other elements. To check is that another element is not consuming the input, try putting event handlers on other elements and see whether or not they trigger.
You can achieve the required outcome by making parent as Canvas instead of Grid and then set ZIndex property to controls inside Canvas , The Control which has highest ZIndex Will appear at front and then you can perform your required operation on it.
<Canvas>
<Image x:Name="img" Source="{Binding ImagePath, Source={x:Static vm:DrawingVM.instance}, Converter={StaticResource nullImageConverter}}" Stretch="None" Panel.ZIndex="0">
</Image>
<ItemsControl ItemsSource="{Binding ListRectangle, Source={x:Static vm:DrawingVM.instance}}" Panel.ZIndex="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="cnvas" Width="{Binding ElementName=img, Path=ActualWidth}"
Height="{Binding ElementName=img,Path=ActualHeight}"
LayoutTransform="{Binding ElementName=img, Path=LayoutTransform}">
<!--MouseDown="cnvas_MouseDown" MouseLeftButtonDown="cnvas_MouseLeftButtonDown"-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<ei:CallMethodAction MethodName="MouseDownDrawing" TargetObject="{Binding Source={x:Static vm:ResizerVM.instance}}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<ei:CallMethodAction MethodName="MouseMoveDrawing" TargetObject="{Binding Source={x:Static vm:ResizerVM.instance}}" />
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown" >
<ei:CallMethodAction MethodName="OnLeftButtonClicked" TargetObject="{Binding Source={x:Static vm:ResizerVM.instance}}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonDown" >
<ei:CallMethodAction MethodName="MouseLeftButtonDownClicked" TargetObject="{Binding Source={x:Static vm:ResizerVM.instance}}" />
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp" >
<ei:CallMethodAction MethodName="DragFinishedMouseHandler" TargetObject="{Binding Source={x:Static vm:ResizerVM.instance}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="Blue" Fill="Transparent" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
I have a code behind in my XAML : when a condition is checked the targets rows will be Orange.
This is the result :
This is the code behind in XAML.cs:
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
foreach (TrainOrdersClass item in dgBaseProd.ItemsSource)
{
var row = dgBaseProd.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
if ((item.IsOverFilled == true) || (item.IsOverWeighed == true))
{
row.Background = Brushes.Orange;
}
}
}
the problem is that when i click on the headers of DataGrid, all the colors is disappeared !
The Xaml:
<DataGrid Name="DataGrid" AutoGenerateColumns="False"
Height="Auto" Width="780" Margin="10,10,10,10"
IsReadOnly="True" ItemsSource="{Binding Path=PreloadedRailcarstList}"
SelectedItem="{Binding Path=BaseProductToUpdate}"
AlternationCount="2" AlternatingRowBackground="LightBlue" Loaded="DataGrid_Loaded" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding Path=DataContext.OpenUpdateBaseProductViewCmd , RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding BaseProductToUpdate.name}"/>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewKeyDown">
<i:InvokeCommandAction Command="{Binding Path=DataContext.OpenUpdateBaseProductViewCmd , RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding BaseProductToUpdate.name}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
//..
How can I fix it ?
thanks,
Define a RowStyle where you set the Background using DataTriggers:
<DataGrid Name="DataGrid" AutoGenerateColumns="False"
Height="Auto" Width="780" Margin="10,10,10,10"
IsReadOnly="True" ItemsSource="{Binding Path=PreloadedRailcarstList}"
SelectedItem="{Binding Path=BaseProductToUpdate}"
AlternationCount="2" AlternatingRowBackground="LightBlue">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding IsOverFilled}" Value="True">
<Setter Property="Background" Value="Orange" />
</DataTrigger>
<DataTrigger Binding="{Binding IsOverWeighed}" Value="True">
<Setter Property="Background" Value="Orange" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding Path=DataContext.OpenUpdateBaseProductViewCmd , RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding BaseProductToUpdate.name}"/>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewKeyDown">
<i:InvokeCommandAction Command="{Binding Path=DataContext.OpenUpdateBaseProductViewCmd , RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding BaseProductToUpdate.name}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
...
</DataGrid>
Don't use code-behind.
I'm building an application with WPF in MVVM style. I'm trying to make filter on my DataGrid when I check or uncheck several CheckBoxes for filtering.
I've found solution with Interaction.Triggers, but it's not working for me in this case.
Here is my code:
<ListBox
ItemsSource="{Binding PortsFilterSource}"
Background="LightGray"
BorderThickness="0"
Grid.Column="1">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox
Content="{Binding Name}"
IsChecked="{Binding IsChecked}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding FilterCommand}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding FilterCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Everything is working great except FilterCommand. I have this in my C# code:
public DelegateCommand<object> FilterCommand { get; set; }
...
FilterCommand = new DelegateCommand<object>(Filter);
Filter(object obj) is a function, but it is not entered when I check or uncheck any of my CheckBoxes.
Any help would be very appreciated.
The problem is, that the data context of the list item is of type FilterModel, but the FilterCommand is in the parent view model.
Try the following binding for the command:
{Binding DataContext.FilterCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}
this is work for me.
<DataGridTemplateColumn Header="IsApved" IsReadOnly="False" CanUserSort="False" Width="55">
<DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<CheckBox
Content="{Binding Name}"
IsChecked="{Binding IsSelect,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding DataContext.CheckCommand,RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding DataContext.CheckCommand,RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I am trying to get selected value from list into the command. Is there simple way to bind commandparameter to selected item?
<ComboBox HorizontalAlignment="Left" Margin="-56,10,0,0" VerticalAlignment="Top" Width="120" SelectedIndex="0" ItemsSource="{Binding Time}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding TestCommand}" CommandParameter="{Binding }"></i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding TestCommand}" CommandParameter="{Binding }"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
When i tried something like
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding TestCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}},Path=SelectionBoxItem}"></i:InvokeCommandAction>
</i:EventTrigger>
it's strange stuck why?
<ComboBox x:Name="Combo" HorizontalAlignment="Left" Margin="-56,10,0,0" VerticalAlignment="Top" Width="120" SelectedIndex="0" ItemsSource="{Binding Time}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding TestCommand}" CommandParameter="{Binding ElementName=Combo, Path=SelectedItem}"></i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding TestCommand}" CommandParameter="{Binding }"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
if you give your combo box a name you can use the ElementName binding and bind to the Path SelectedItem
I am having an Wpf application it has a Combobox.
which contains a checkbox and Textblock when i click on the checkbox
it shows the selected country string in the combobox but if i click on text it shows me a error string as shown in image.
I want to show the country name even if the user clicks on the textblock.
My xaml looks like this
<ComboBox Text="{Binding CurrentCountries}" ToolTip="{Binding CurrentCountries}" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Name="cmbCountry" IsEditable="True" IsReadOnly="True" TextSearch.TextPath="{Binding CountryName}" HorizontalContentAlignment="Left" Margin="80,14,0,0" VerticalAlignment="Top" Width="100 " ItemsSource="{Binding Country, Mode=TwoWay}" SelectedItem="{Binding SelectedCountry,Mode= TwoWay}" Height="22" TabIndex="1">
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Name="Country" HorizontalAlignment="Left" Grid.Column="0" Content="{Binding CountryName}" IsChecked="{Binding IsChecked}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<Commands:EventToCommand Command="{Binding DataContext.CountryCheckedCmd,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadWindow}}}" CommandParameter="{Binding ElementName=Country}" ></Commands:EventToCommand>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<Commands:EventToCommand Command="{Binding DataContext.CountryUnCheckedCmd,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadWindow}}}" CommandParameter="{Binding ElementName=Country}" ></Commands:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
thank you!
If you want to multiselection ComboBox you should use CheckComboBox from WPF Extended Toolkit.
It's very easy to using, example:
<xctk:CheckComboBox x:Name="_combo"
HorizontalAlignment="Center"
VerticalAlignment="Center"
DisplayMemberPath="Color"
ValueMemberPath="Level"
SelectedValue="{Binding SelectedValue}"
SelectedItems="{Binding SelectedItems}" />