I have a combo box with radio buttons and checkable menu items. When I select a value some text of the radio buttons (Include / Exclude / Ignore) is displayed. This seems to be randomly and does not happen always, but only sometimes.
What I want is that a) no text at all is displayed or b) I can have a binding for a string property, which will contain some summary of what is selected. Unlike in normal combo boxes, the displayed text here is meaningless, since I do select some arbitrary combination of options (not a single value out of a list)
I have tried to bind Text / SelecteValue against a property, but this does not work.
<ComboBox Grid.Column="2" HorizontalAlignment="Left" Margin="0,4,0,0" Grid.Row="3" VerticalAlignment="Top" Width="125" SelectedValue="{Binding Settings.NameFilterTrx.Summary, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}">
<MenuItem Header="Names with runway" IsCheckable="True" IsChecked="{Binding Settings.NameFilterTrx.NamesWithRunway, UpdateSourceTrigger=PropertyChanged}"/>
<MenuItem Header="Names with number" IsCheckable="True" IsChecked="{Binding Settings.NameFilterTrxNamesWithNumber, UpdateSourceTrigger=PropertyChanged}"/>
<MenuItem Header="Filtered elements as comments" IsCheckable="True" IsChecked="{Binding Settings.NameFilterTrx.FilteredAsComments, UpdateSourceTrigger=PropertyChanged}"/>
<RadioButton GroupName="Group" Content="Exclude" IsChecked="{Binding Settings.NameFilterTrx.ModeExclude, UpdateSourceTrigger=PropertyChanged}" Margin="10,2,0,3"/>
<RadioButton GroupName="Group" Content="Include" IsChecked="{Binding Settings.NameFilterTrx.ModeInclude, UpdateSourceTrigger=PropertyChanged}" Margin="10,2,0,3"/>
<RadioButton GroupName="Group" Content="Ignore" IsChecked="{Binding Settings.NameFilterTrx.ModeIgnore, UpdateSourceTrigger=PropertyChanged}" Margin="10,2,0,3"/>
</ComboBox>
As you can see the text does not correspond with the selected value. Also only text of the radio buttons is randomly displayed, never something of the menu items.
PS: The binding for SelectedValue is one of my trails to get a defined value. If have tried Text as well as no binding.
I think you could use an expander to fullfill your goal. The problem with this solution is that when the Expander is expanded, it may change the size of your parent container. So what I usually do is to put it in a Grid and specify it to span several rows and columns. Then I will set the z-index of the Expander to a large value. So the expanded Expander will overlay the other controls and not change the size of the parent panel. :)
Related
Alright, so this might be a bit hard to explain. I'm putting together a quick scheduling application and for displaying the calendar and the shifts I'm using two nested ListViews (one ListView to display the calendar day and the inner ListView to display the shifts). The problem I'm encountering is that if I click directly into the child ListView that contains the shifts, my parent ListView's SelectedItem doesn't change. I have a contextmenu that will add a new shift when clicked, but since the parent's SelectedItem isn't changing it will add to the wrong day of the month.
Here's some visuals of what I'm talking about:
Calendar Screenshot
Here's a general idea of the code I'm talking about:
<ListView ItemsSource="{Binding Schedule.Days}" SelectedItem="{Binding SelectedDay}">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="Add New Shift" Command="{Binding AddNewShift}"/>
<MenuItem Header="Edit Shift" Command="{Binding EditShift}"/>
<MenuItem Header="Delete Shift" Command="{Binding DeleteShift}"/>
</ContextMenu>
</ListView.ContextMenu>
<ListView.ItemTemplate>
<DataTemplate>
<ListView ItemsSource="{Binding Shifts}" SelectedItem="{Binding SelectedShift}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So when I click directly into the ListView containing Shifts, the SelectedDay of the parent ListView doesn't change, that's the problem I'm trying to address.
I have the following ComboBox XAML:
<ComboBox Width="350" ItemsSource="{Binding RunSets}" SelectedItem="{Binding SelectedRunSet, Mode=OneWay}" VerticalAlignment="Center" Height="20" Margin="5,1,0,0" Background="DimGray" Foreground="White" >
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid Width="320">
<CheckBox IsChecked="{Binding IsSelected}" Margin="2,2,10,0" Visibility="{Binding ExchangeMarketNamesVisibility}" PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown">
<CheckBox.Content>
<StackPanel PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown">
<StackPanel Orientation="Horizontal" PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown">
<TextBlock Text="{Binding DisplayName}" PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown"/>
</StackPanel>
<StackPanel PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown">
<TextBlock Text="{Binding ExchangeMarketNames, StringFormat=🢒 {0}}" Visibility="{Binding ExchangeMarketNamesVisibility}" Margin="2,2,0,2" Foreground="LightGray" PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown" />
</StackPanel>
</StackPanel>
</CheckBox.Content>
</CheckBox>
<TextBlock Text="Select Items..." Visibility="{Binding DefaultItemVisibility}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The goal I'm trying to achieve is to have the ComboBox present a set of selectable ComboBoxItems. It should always display "Select Items" when closed:
And when opened I would like it to display the following:
When the highlighted area is clicked it should check the checkbox without closing the combobox. I have managed to get most of the behaviour I want by hacking the Visibility property to hide the checkbox in the "Select Items..." ComboBoxItem. Together with capturing the PreviewMouseDown event:
private void RunsetComboBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var checkBox = sender as CheckBox;
if(checkBox != null)
{
checkBox.IsChecked = !checkBox.IsChecked;
e.Handled = true;
}
}
This is almost working perfectly, but there are two issues that I can't resolve:
If I click on the border between the ComboBoxItems in the dropdown it will select that ComboBoxItem. I want it to never select any of them. I have managed to work around for clicks inside the highlighted area by capturing the preview mouse down event on the Grid in the and marking it handled. Unfortunately in the border this doesn't get triggered and the SelectedItemChanged event gets triggered on the ComboBox. This causes the selected item to change (as mentioned, I want the ComboBox to always display the "Select Items..." ComboBoxItem.
The "Select Items..." is shown twice when the combo box is expaned. I would like it to show just once.
I have managed to get most of the behaviour I want by hacking the Visibility property to hide the checkbox in the "Select Items..." ComboBoxItem together with capturing the PreviewMouseDown event.
I have read through many stack overflow posts about this, and I have not found a way of doing this. I tried capturing the SelectionChange and marking it handled but it closed the combobox anyway, and there is no PreviewSelectionChange event. When an item is selected I'd like the combobox to stay open.
Is there any way I can achieve this? Please let me know if there's any more information I can add to clarify my problem. Thanks!
I have a combobox which works as directory selector. Visually its items are checkboxes, each checkbox is directory. User can check any of the checkboxes and this way make a selection of 2, 3, 10, you name it, directories.
This is the combobox binding:
<ComboBox ItemsSource="{Binding Path=KnownDirectories}"
IsEditable="True" IsReadOnly="True" Text="{Binding Path=WorkingDirectory}">
It works.
What does not work is a case when user clicks not at the chekbox rectangle, but somewhere else, so it is the case when user actually selects the row, not switches the checkbox. In this case WPF selects the row, and sets its ToString representation (which is name of the type in this case) as WorkingDirectory.
As the effect, instead of something like "C:\my_dir" I see "DirectoryType".
How to disable this automatic selection when user selects (clicks) entire row instead of clicking on checkbox toggle?
Temporarily I simply overrode ToString in my DirectoryType.
Initial item template for combobox:
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Path=IsDirectorySelected}">
<Label Content="{Binding Path=DirectoryName}" />
</CheckBox>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
After Ash suggestion (all errors are mine):
<DataTemplate>
<ComboBoxItem IsSelected="{Binding Path=IsDirectorySelected}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ComboBoxItem}},Path=IsSelected}">
<Label Content="{Binding Path=DirectoryName}" />
</CheckBox>
</StackPanel>
</ComboBoxItem>
</DataTemplate>
My problem is twofold, but i guess that they are related, and if I manage to fix one of them, I will solve both.
First of, lets see the xaml code for a ContextMenu that is linked to a Caliburn.Micro view model:
<ContextMenu>
<MenuItem Header="Configure modem" ItemsSource="{Binding Modems}">
<MenuItem.ItemTemplate>
<DataTemplate>
<MenuItem>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ca:ActionMessage MethodName="SelectModem">
<ca:Parameter Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
</ca:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
<MenuItem.Header>
<DockPanel>
<Image DockPanel.Dock="Left" Source="{Binding CarrierProfile.CarrierProfileIcon}" Width="40" Height="40"/>
<TextBlock Text="{Binding MenuText}" VerticalAlignment="Center" Margin="10 0"/>
</DockPanel>
</MenuItem.Header>
</MenuItem>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
</ContextMenu>
So basically this is just a DataTemplate where I set the Header to a DockPanel containing an image and a TextBlock.
One MenuItem looks like this:
Here you can see the main problem. You can see that there are "two selections". One outer selection, and one inner. If I click the inner selection, everything is fine, and my SelectModem method is called from my view model. However, if you click the outer selection the context menu goes away so that user thinks he has made a selection, but actually no method is called on the view model.
My second problem is that if I disable the MenuItem by adding IsEnabled="False" in the code above, the menu item looks disabled (text is grayed out), I cannot make the inner selection, but on hover is still shows the outer selection, and when clicked the menu goes away (but nothing is triggered in my view model)
So the question is: How can I get rid of the the outer selection?
I have a context menu and checkbox inside it, but checkbox displays not correctly.
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu >
<toolkit:MenuItem Click="iLikeIt" Tag="{Binding ElementName=chbox}" Header="{Binding isLikeMe, Converter={StaticResource LikeIt}}"/>
<toolkit:MenuItem>
<toolkit:MenuItem.Header>
<CheckBox Name="chbox" Tag="{Binding}" BorderThickness="1" Content="Рассказать друзьям" >
</CheckBox>
</toolkit:MenuItem.Header>
</toolkit:MenuItem>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
As this is a UI issue and not a functional one this is very likely a styling issue with the CheckBox. You will need to apply a custom style to the CheckBox in the ContextMenu so that it looks OK in the inverted colours of the ContextMenu.
Make sure you make it work in both Dark and Light theme though.