WPF Combo box + MouseLeftButtonDown - wpf

Hopefully someone can help because I haven't been able to figure this out. Here's my xaml code for the popup/combo box, please not there is other code before and after this for the rest of the layout.
<Popup x:Name="popupMethods" Height="400" Width="150"
StaysOpen="False" Placement="Bottom" IsOpen="false"
HorizontalAlignment="Left">
<ComboBox x:Name="combo" MouseLeftButtonDown="combo_MouseDown">
<TextBlock>Hello</TextBlock>
<TextBlock>World</TextBlock>
<TextBlock>This</TextBlock>
<TextBlock>is</TextBlock>
<TextBlock>Autocomplete</TextBlock>
<TextBlock>Textbox</TextBlock>
</ComboBox>
</Popup>
Have it set up to popup on the screen whenever the user starts typing, which works. The problem is I want the user to be able to click one of the words in the combo box and that gets inserted into the text box. This parts not working as the MouseLeftButtonDown is never being fired. I've tried a couple of different methods including the one from this site
http://www.designerwpf.com/2008/12/03/getting-a-mouseleftbuttondown-or-mouseleftbuttonup-
event-from-your-textbox/
as well as one I saw somewhere else that was combo.MouseLeftButtonDown += delegate { };
Thanks for any help.

Instead of MouseLeftButtonDown event handler, use PreviewMouseLeftButtonDown you can achieve the same.

You probably want to look at the SelectionChanged event. It fires whenever an item in the ComboBox's drop down is selected.
I think that the ComboBox internally handles the MouseLeftButtonDown event, and that is causing it not to be passed on to your code.

Related

How add a complete Click MouseGesture to a ListBoxItem in XAML

I have a ListBoxItem with a LeftClick Gesture:
<ListBoxItem x:Name="ListViewItemMenu" Content="{Binding Path=Header}" Padding="37 14" FontSize="15" Foreground="White">
<ListBoxItem.InputBindings>
<MouseBinding Gesture="LeftClick" Command="ApplicationCommands.New" />
</ListBoxItem.InputBindings>
</ListBoxItem>
But actually it's not a real Click, it's simply a MouseLeftButtonDown Gesture. The Command is executed regardless of whether the button is raised or not after pressed.
I would like to have a complete Click with the MouseDown and MouseUp Gestures in the ListBoxItem. There is anyway to do that? Much appreciated.
Also I can't find a way to add a Command to an Expander. The method shown above to the ListBoxItem doesn't work. Any magic here? Thanks!
According to this answer you can inherit from MouseGesture to create custom gestures. There is even a full example with implementation.
An alternative is to use an System.Windows.Interactivity.EventTrigger as shown in this answer, which would let you turn the MouseLeftButtonUp or PreviewMouseLeftButtonUp event into a command trigger.

How to override PreviewKeyDown on a TextBox?

I have a handler for the PreviewKeyDown event on a TextBox inside a control I made, which checks to see if the user has pressed the down key. The event handler correctly handles the key press when the control sits inside a layout container like a grid. If however, I place the control inside a DataGrid's DataGridTempalteColumn, the control does not do what I need it to do.
I think the issue is that because the PreviewKeyDown is on a Tunneling strategy, the host DataGrid gets to handle the down arrow key press before my control does. For the down arrow the DataGrid moves the focus to the next row. The DataGrid doesn't seem to be setting the IsHandled to true, because it the event eventually gets down to my control, but it does nevertheless do its own thing on the event, which breaks things for me.
The issue isn't really with the DataGrid, but with the fact that my control has a tunneling PreviewKeyDown event from the TextBox. I'm looking for a way to override this default event on the TextBox. Perhaps there's something I can do with attached behaviors? Maybe I need to inherit from the TextBox and then override? So far I've not found anything that indicates how to handle a situation like this.
Below is the original text for this question that didn't yield any answers
I'm having difficulty using a custom autocomplete text box I made as a DataTemplate in a DataGridTemplateColumn.
<DataGrid.Columns>
<DataGridTemplateColumn Header="Material" Width="300">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<local:actextbox Text="{Binding Path=Description, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
MatchList="{Binding Path=DataContext.LaborTemplatesList, RelativeSource={RelativeSource AncestorType=UserControl, AncestorLevel=2}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Description}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
The actextbox class derives from user control and has event handlers to respond to certain key presses like so
private void myTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Down & myPopup.IsOpen == true)
{
myPopUpList.SelectedIndex = 0;
ListBoxItem lbi = (ListBoxItem)myPopUpList.ItemContainerGenerator.ContainerFromItem(myPopUpList.SelectedItem);
lbi.Focus();
e.Handled = true;
}
}
The intent is that when an autocomplete popup is displayed, pressing down and up allows the user to navigate its contents. This works as expected when the control is placed in a hierarchy of layout containers; however, when it is part of the cell in a datagrid the expected behaviour is lost. Looks like the previewKeyDown is used by the DataGrid to apply its own interpretation of the down or up arrows, and while it does not set the event as handled, by the time the event gets down to my control focus is lost, and different row is selected.
I've looked online all over, and wasn't able to find any clues on how to handle this. Certainly, I've seen controls inside DataGridTemplateColumns handle all sorts of inputs, but how they accomplish this is lost on me.
OK, following some advice to use Snoop I figured out what was happening. In fact the issue was not that the DataGrid was doing something with the PreviewKEyDown event, but that I was moving focus away from the data grid cell that was presently being edited triggering a CellEditEnding event. This resulted in the behaviour I was observing.

Try to catch mouse event in HierarchicalDataTemplate

I'm fairly new to wpf and this website. Please give me some mercy if I show some mistakes.
My HierarchicalDataTemplate ,which is my treeview item, consists of multiple components: two textblocks , image , and checkbox with some stack panels for the layout. My MouseEventHandler, which is to catch when user click on textboxes, image , or checkbox , is TreeViewItem.Selected. But when I click on the tiny space between those components, it doesn't trigger TreeViewItem.Selected.
My first initial thought was that I might need to specify event handler on the stack panel which was for the layout of my HierarchicalDataTemplate . However, it didn't rise the event ,even though I made event handler on stack panel specifically.
Could you give me some guidance?
ps. I used binding for IsSelected property but it never notified to change its property
Set Background="Transparent" for topmost layout container inside your HierarchicalDataTemplate.
The following Grid doesn't raise MouseLeftButtonDown event:
<Grid MouseLeftButtonDown="handler" Width="200" Height="200">
</Grid>
But the following does:
<Grid MouseLeftButtonDown="handler" Width="200" Height="200" Background="Transparent">
</Grid>
This is because in the 1st case it doesn't have background and there's nothing to raise MouseLeftButtonDown event. So the event will be raised only if user clicks on some element inside that Grid.

Embedded ComboBox in Button, but Button steals click event when activating drop down

I have an application with limited screen space, so I'm trying to conserve some real estate by putting a combo box within a button. Its pretty nifty and it looks exactly like what I wanted it to look like. The problem is, every time I click the down arrow on the combo box, the Button also receives a click event. The drop down menu still works properly, but my button has already fired before I've had a chance to actually select what I wanted.
Here is my WPF code that describes my Button and its contents.
<Button FontSize="14" Height="32" HorizontalAlignment="Left" Click="DisableCopierButton_Click">
<StackPanel Orientation="Horizontal">
<Label Content="Disable Copier:" />
<ComboBox Name="DisableCopierComboBox">
<ComboBoxItem Content="1"/>
<ComboBoxItem Content="2"/>
</ComboBox>
</StackPanel>
</Button>
My question is, when I'm clicking on the ComboBox and only the ComboBox, how do I prevent the click event from passing through the button that is underneath it?
I finally found it. I went with the solution provided by Rachel here, even though it was not selected as the answer.
private void EnableCopierButton_Click(object sender, RoutedEventArgs e)
{
if (!(e.OriginalSource is Button))
{
// combo box was clicked, not the button, so get out of here.
return;
}
}
This seems like a SplitButton, yeah. Don't reinvent the wheel. Plenty of implementations on the web.
I recommend WPF Toolkit Extended's.
Rather than making the combo box be part of the button's Content, you may want to try creating a ContentTemplate for the button that includes a combo box.

AutoCompleteBox with TextChanged event not selecting properly

Hi I'm using an AutoCompleteBox like this
<!-- XAML Code -->
<sdk:AutoCompleteBox Grid.Row="2"
FilterMode="None"
ItemsSource="{Binding Customers}"
SelectedItem="{Binding Path=SelectedCustomer, Mode=TwoWay}"
Text="{Binding CustomerSearchString, Mode=TwoWay}"
ValueMemberBinding="{Binding Path=FullName}"
ValueMemberPath="FullName"
TextChanged="{ext:Invoke MethodName=Search, Source={Binding}}"/>
C# part:
// Search Method in the viewmodel
public void Search()
{
var customerOperation = _context.Load(_context.GetCustomerByNameQuery(CustomerSearchString));
customerOperation.Completed += (s, e) => Customers = new List<Customer>(customerOperation.Entities);
}
In my app to quick-search for customers for an fast and uncomplicated method to search. I get it to display everything correctly in the dropdown, and when I select with the mouse it works perfectly.
But when I press ArrowDown, you see the text come up for a split-second but then it reverts and puts the cursor back in the textbox instead of selecting the first entry down. I tried using the TextInput event, but that one won't fire.
How can I avoid this behaviour?
SOLUTION:
The problem was, that the TextChanged event got fired when the user selected an entry, creating some sort of race condition like behaviour where the Text got reset. The solution was to use the KeyUp event (don't use KeyDown, because the Text property won't be updated yet). This event doesn't get triggered when the user selects something, solving the problem.
Final code (ViewModel unchanged):
<!-- XAML Code -->
<sdk:AutoCompleteBox Grid.Row="2"
FilterMode="None"
ItemsSource="{Binding Customers}"
SelectedItem="{Binding Path=SelectedCustomer, Mode=TwoWay}"
Text="{Binding CustomerSearchString, Mode=TwoWay}"
ValueMemberBinding="{Binding Path=FullName}"
ValueMemberPath="FullName"
KeyUp="{ext:Invoke MethodName=Search, Source={Binding}}"/>
Thanks everyone!
Add a handler like this in code:
KeyEventHandler eventHandler = MyAutoCompleteBox_KeyDown;
MyAutoCompleteBox.AddHandler(KeyDownEvent, eventHandler, true);
I'm not understanding why you are using a TextChanged event...? What is that for? If you take that out, does it work? I use an autocomplete box in my project and I don't need a search method... all I do is just supply a list of objects to the autocompletebox and the it searches that list when the user types. I can select either by mouse or by up/down arrows. The only thing that I can think of is that each time you try to use the up/down arrow the text changes and fires off the search function and closes the selection option drop down...

Resources