ContextMenu closing when clicking an inner control - wpf

I have a textbox with a ContextMenu, the menu contains a tab control. The problem I'm running into is that when I click any of the tab control items to change the visible tab control item the Context Menu gets closed. Any ideas?
I've tried the ContextMenu_ContextMenuClosing event but it doesn't appear to catch the event
<TextBox x:Name="TestCB4" TextSearch.TextPath="Name" >
<TextBox.ContextMenu>
<ContextMenu ContextMenuOpening="ContextMenu_ContextMenuOpening"
ContextMenuClosing="ContextMenu_ContextMenuClosing"
MouseLeftButtonDown="ContextMenu_MouseLeftButtonDown"
StaysOpen="True"
Background="Transparent" Margin="0">
<TabControl ContextMenuClosing="TabControl_ContextMenuClosing" Margin="0">
<TabItem Header="User Space">
<WrapPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="10,2,2,2">
<Button Content="_Select" Margin="1"
Command="{Binding Path=SelectVendorCommand}"
CommandParameter="{Binding ElementName=ucFindVendorCtrl, Path=VendorListView.SelectedItems}" />
<Button Content="_Add To User Space" Margin="1"
Command="{Binding Path=AddVendorToUserSpaceCommand}"
Width="120"
CommandParameter="{Binding ElementName=ucFindVendorCtrl, Path=VendorListView.SelectedItems}" />
</WrapPanel>
</TabItem>
<TabItem Header="Find">
<WrapPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="10,2,2,2">
<Button Content="_Select" Margin="1"
Command="{Binding Path=SelectVendorCommand}"
CommandParameter="{Binding ElementName=ucFindVendorCtrl, Path=VendorListView.SelectedItems}" />
<Button Content="_Add To User Space" Margin="1"
Command="{Binding Path=AddVendorToUserSpaceCommand}"
Width="120"
CommandParameter="{Binding ElementName=ucFindVendorCtrl, Path=VendorListView.SelectedItems}" />
</WrapPanel>
</TabItem>
</TabControl>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>

I think that the problem is that the TabControl does not handle the propagation of the MouseLeftButtonDown routed events, and so the ContextMenu catches it, and closes.
If that's the case, then the solution is rather simple. Just wrap the TabControl in a ContentControl, and catch the event MouseLeftButtonDown on the ContentControl. In the event handler do e.Handled = true;
This way the ContextMenu would have no way of knowing that the user has clicked on the TabControl.

try to put your tabcontrol inside a menuItem like the example:
<ContextMenu>
<MenuItem StaysOpenOnClick="true">
<MenuItem.Header>
...your TabControl
</MenuItem.Header>
</MenuItem>
</ContextMenu>
I hope that it can be helpful.

Related

Is it possible to make the contents of a ScrollViewer scroll with the mouse wheel?

I'm on a team of developers working on a new WPF application. We've got a usercontrol on the MainWindow which has a ScrollViewer. We've got VerticalScrollBarVisibility="Auto" set, which works fine, if the contents within the ScrollViewer become larger than the available space for the ScrollViewer. However, what doesn't happen, which I wish would happen, is the user cannot scroll the contents with the mouse wheel. In other places where we're using DataGrids, if the content of the DataGrid is larger than can be displayed vertically, the user can scroll the contents vertically using their mouse wheel. But they cannot do so within the ScrollViewer in the user control on MainWindow. If it's possible to make the contents scroll vertically with the mouse wheel, how is it done?
Here's a snippet of the ScrollViewer, with content removed for brevity:
<ScrollViewer
Grid.Row="1"
Margin="0,20,0,0"
Width="300"
VerticalScrollBarVisibility="Auto"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<StackPanel>
<Expander
x:Name="PeopleSideExpander"
IsExpanded="{Binding PeopleSideIsExpanded}"
IsEnabled="True">
<Expander.Header>
<Button
x:Name="tilePeopleSide"
Content="People Side"
Command="{Binding PeopleSideExpanderCommand}"
Cursor="Hand" />
</Expander.Header>
<ListBox>
<ListBoxItem>
<Button Name="tileAgency" Content="Agencies" Command="{Binding ViewAgencyCommand}" />
</ListBoxItem>
<ListBoxItem>
<Button Name="tilePerson" Content="Personnel" Command="{Binding ViewPersonCommand}" />
</ListBoxItem>
<!-- Several other ListBoxItems removed for brevity -->
</ListBox>
</Expander>
<Expander
x:Name="HardwareSideExpander"
Grid.Row="1"
IsExpanded="{Binding HardwareSideIsExpanded}"
IsEnabled="True">
<Expander.Header>
<Button
x:Name="tileHardwareSide"
Content="Hardware Side"
Command="{Binding HardwareSideExpanderCommand}"
Cursor="Hand" />
</Expander.Header>
<ListBox>
<ListBoxItem>
<Button Name="tileEvent"
Content="Event"
IsEnabled="False"
Foreground="LightGray"
Command="{Binding ViewEventCommand}" />
</ListBoxItem>
<ListBoxItem>
<Button Name="tileInstrument"
Content="Instrument"
IsEnabled="False"
Foreground="LightGray"
Command="{Binding ViewInstrumentCommand}" />
</ListBoxItem>
<ListBoxItem>
<Button x:Name="tileHardwareProficiency"
Content="Proficiencies"
Visibility="Collapsed"
ToolTip="Not Implemented" />
</ListBoxItem>
<ListBoxItem>
<Button x:Name="tileSolution"
Content="Proficiency Solutions"
Command="{Binding ViewSolutionCommand}" />
</ListBoxItem>
</ListBox>
</Expander>
</StackPanel>
</ScrollViewer>

stackpanel containing button does not fire command wpf

I have a stackpanel that contains many elements including buttons. I am not able to fire a method through ICommands. It works through adding an event handler in the code behind for the Button.Click event. Since, I am following a MVVM pattern, I want to fire a command. Also, this stackpanel is a datatemplate for my listviewitem.
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" IsHitTestVisible="True">
<Button Cursor="Hand" Command="{Binding MoveImageUp}">
<Button.Background>
<ImageBrush ImageSource="..."/>
</Button.Background>
</Button>
<Grid>
<Image Source="{Binding Path=Image}"/>
<TextBlock Height="20" Width="20" Text="{Binding Path=Order}" Opacity="0.8" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
<GridSplitter HorizontalAlignment="Center" Padding="1" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
I have tried setting IsHitTestVisibile to true, does not work.
There was no DataContext set for the button. Thanks #Foggy Finder
<Button Cursor="Hand" Command="{Binding ElementName=ImagesList, Path=DataContext.MoveImageUp}" CommandParameter="{Binding}">

How do I close a Popup that contains Menu when one of the MenuItems is selected (DataGridCell)

I am having a problem using a Popup that contains a dynamic Menu within a DataGridCell. I can get the popup to appear just fine, and disappear when focus is lost by clicking anywhere else in the window. But, I cannot get the popup to disappear when one of the MenuItems is selected.
Here is the XAML for my CellTemplate:
<DockPanel>
<ToggleButton Content=" + "
FontWeight="Bold"
FontFamily="Arial"
Foreground="Green"
BorderBrush="Transparent"
IsThreeState="False"
DockPanel.Dock="Right"
Name="Button_AddDefinition">
</ToggleButton>
<Popup IsOpen="{Binding ElementName=Button_AddDefinition, Path=IsChecked}"
StaysOpen="False"
Placement="Right"
PlacementTarget="{Binding ElementName=Button_AddDefinition}"
AllowsTransparency="True">
<Border CornerRadius="3"
Background="WhiteSmoke"
BorderBrush="DarkGray"
BorderThickness="1">
<Menu ItemsSource="{Binding Path=NewDefinitionTypes}">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<Menu.ItemTemplate>
<DataTemplate >
<MenuItem Header="{Binding StringFormat='New {0}'}"
Command="{Binding RelativeSource={RelativeSource AncestorType=Popup}, Path=DataContext.NewDefinitionCommand}"
CommandParameter="{Binding}">
</MenuItem>
</DataTemplate>
</Menu.ItemTemplate>
</Menu>
</Border>
</Popup>
<ComboBox SelectedItem="{Binding Path=Definition, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True, ValidatesOnDataErrors=True}"
ItemsSource="{Binding Path=AvailableDefinitions}"
BorderBrush="Transparent"
MouseUp="DataGridCell_ComboBox_MouseUp"
DisplayMemberPath="Name"
Style="{StaticResource ValidationErrorStyle}">
</ComboBox>
</DockPanel>
When I click the toggle button (i.e. the '+') I get the popup, dynamically populated to have a menu item each item. Here is what it looks like:
When I click anywhere else outside the popup, the popup disappears (what I want). But, when I click one of the items, I also want the popup to process the selection, and then the popup should go away. That is what I'm looking for here. How can I make the popup disappear once an item inside it is selected. I'm working on an MVVM platform, so minimal code-behind is preferred, but not dogma.
Any ideas?

How to make a WPF ComboBox to handle click on an overlying TextBlock?

I have a TextBlock which is over a ComboBox and I want the combobox popup (dropdown) apear when I click on it.
<Grid>
<ComboBox Name="tstcmb" Height="27" HorizontalAlignment="Left" Margin="29,92,0,0" VerticalAlignment="Top" Width="131" SelectedIndex="1" >
<ComboBoxItem>a</ComboBoxItem>
<ComboBoxItem>aaaa</ComboBoxItem>
</ComboBox>
<TextBlock Text="skdkdkdk" Background="Green" Height="16" HorizontalAlignment="Left" Margin="29,92,0,0" VerticalAlignment="Top" Width="131" />
</Grid>
Is it possible?
Set IsHitTestVisible="False"
<TextBlock IsHitTestVisible="False".../>
In that way the TextBlock doesn't intercept mouse clicks and allows them to be handled by the ComboBox underneath.

ListBox with Button in ItemTemplate: fire SelectedChanged on Button Click

I have a ListBox with Button in ItemTemplate. When I press a Button, some Command fired. I want the ListBox to fire SelectionChanged event when Button Click event happen. How shoult I fire ListBox SelectionChanged event and pass appropriate context?
<ListBox ItemsSource="{Binding SomeSource}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Button Grid.Row="0" BorderThickness="0" Background="Transparent" HorizontalAlignment="Stretch">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding SomeCommand}" CommandParameter="{Binding}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Button.Template>
<ControlTemplate>
<TextBlock Text="{Binding Title}" />
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If you can have a SelectedItem property in the ViewModel you can TwoWay bind that to the ListBox.Selecteditem and in the SomeCommand implementation you can set the ViewModel.SelectedItem so that it reflects to the UI and you get SelectionChanged call.

Resources