I have an issue with editable combobox. I can get textbox PART_EditableTextBox and make it multiline by AcceptsReturn="True" and TextWrapping="Wrap".
The problem I have is that I cannot make it work like classic textbox for text operations.
For example key down does not navigate in text and instead just fire item selection even if there is just 1 item in my collection it effectively refresh to original value. Same for scroll bar.
I found that I can catch some events (previewkeydown on parent element/ PreviewMouseWheel) and handle them to not reset value but still missing the text navigation(moving in text by arrows) or having scroll bar.
Edit
I find solution.
Insted of using ComboBox I used ComboBoxEdit from DevExpress.
Now it gets quite easy since they have already implemented property to solve halve of my problems.
this.ComboBoxEdit.AllowSpinOnMouseWheel = false
this.ComboBoxEdit.AcceptsReturn = true;
this.ComboBoxEdit.TextWrapping = TextWrapping.Wrap;
Only problem left was text navigation by arrows.
I catched PreviewKeyDown from parent element and implemented this.
private void Grid_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.OriginalSource is TextBox tx)
{
if (e.Key == Key.Up)
{
EditingCommands.MoveUpByLine.Execute(null, tx);
e.Handled = true;
}
else if (e.Key == Key.Down)
{
EditingCommands.MoveDownByLine.Execute(null, tx);
e.Handled = true;
}
}
}
I think the plan seems like a bad idea.
There are fundamental mismatches between functionality an editable combobox gives and what you seem to require from a multiline textbox inside one.
For one, the arrows already have an inherent meaning to a combobox. That's how you navigate the autocomplete list using keyboard.
An editable combobox is intended to do autocomplete as well as possibly add a new item.
Maybe you could have a textbox and a combobox. The user switches between these using a togglebutton or some such. Depending on whether they want to add new or look up an existing item.
I think your best bet is likely to build your own usercontrol if you particularly need this to look similar to a combobox.
The editable part would be a textbox.
The list of possibles can be a listbox inside a popup or expander.
You could choose whether to use a togglebutton to show your popup like the combobox does, or not.
Add the functionality you need without the problems functionality inherent to a combobox control adds.
Related
I have a ListView that gets populated by an ObservableCollection via Binding. Its ListViewItems should have Focusable="False" as I don't want a TextBox to lose keyboard focus when clicking anything. Unfortunately, this prevents ListViewItems from being selected by clicking on them. How can I make ListViewItems selectable by clicking without changing the current focus?
I tried selecting an item in code by doing
myListView.SelectedIndex = i;
but I couldn't find a way to find the index of the clicked item. I can't use VisualTreeHelper.GetChild() to check for IsMouseOver because the data binding does not actually add controls to the visual tree.
Please don't suggest resetting the focus to the TextBox. The TextBox should not lose focus at all.
I figured it out thanks to this question.
I added PreviewMouseDown="OnMouseDown" to my ListViewItem template (in my case to the Border element) which selects the corresponding item by doing:
private void OnMouseDown(object sender, MouseButtonEventArgs e)
{
var item = (sender as Border).DataContext;
myListView.SelectedIndex = myListView.Items.IndexOf(item);
}
I have a datagrid inside a scrollviewer. The rows of my datagrid can be expanded to show the details and edit the row items.
In order for the "page" to scroll when the number of rows/row details view pushes the grid too long, I am handling the PreviewMouseWheel event on the datagrid. This works until I have a combobox in my row details with a droplist that has enough items that it also needs to scroll.
When using the mouse wheel, the droplist will scroll, but so does the outer datagrid, effectively scrolling the contents "behind" the droplist and leaving the droplist in the wrong place.
My PreviewMouseWheel event handler does the following:
private void StampPartsDatagrid_PreviewMouseWheelForScrolling(object sender, MouseWheelEventArgs e)
{
StampingScrollViewer.ScrollToVerticalOffset(StampingScrollViewer.VerticalOffset - e.Delta / 3);
}
I tried to trap the dropdown/drop up event on the combo, and while that works, if I move the mouse outside the drop list and scroll with the wheel, the page doesn't scroll.
I looked through many articles on MSDN and SO but they were mostly about getting the datagrid to scroll when inside a scrollviewer.
Is there a way to do a hit test on the Preview scrolling event? Should I trap the mouse/enter leave on the droplist somehow? Should I be handling my scrolling differently?
Thanks
* EDIT *
I resolved this issue. I was overthinking the mouse wheel behaviour. By looking at the Windows settings panel page for regions, which has a very long combo list to display, I saw that if the combo list was dropped the mousewheel only applied to he dropped list. Moving the mouse outside the droplist and scrolling with the wheel has no effect.
Given this, I adopted the same behaviour by trapping the drop open /drop close events and controlling the outer scrolling. My new event handler, taken from this post (https://social.msdn.microsoft.com/Forums/vstudio/en-US/6fc503a6-ba53-4395-b9b8-f56301efd097/mousescroll-of-combobox-scrolls-the-page-as-well?forum=wpf) is this:
private void StampPartsDatagrid_PreviewMouseWheelForScrolling(object sender, MouseWheelEventArgs e)
{
if (!bDetailsComboDropped)
{
StampingScrollViewer.ScrollToVerticalOffset(StampingScrollViewer.VerticalOffset - e.Delta / 3);
}
}
If you don't like to have an bDetailsComboDropped field, you can also try to determine where the preview mouse wheel routed event is coming from. Specifically, check e.OriginalSource to get a reference to the WPF element that was actually triggering the event (or e.Source if you find it better for the purpose).
Combine this with a recursive function using VisualTreeHelper.GetParent to check whether any of the parent elements is a combo box part, or it ends with your root scroll viewer.
(Note: your solution with the Boolean flag might actually provide higher performance, I just posted this in case someone needs a source-oriented solution, e.g. if there were many other controls to check against scrolling internally, etc.)
I have an application where I have several forms. Its a C# windows-form based application build in .NET 4.O. I have several forms where the user enters the data. There are grids where data is displayed and whole lots of controls on the form. Believe me! its a mess of so many controls. I have to setup the TabIndex for each control. I have literally disabled the TabStop property of certain controls I don't want to be tabed into it. However, still once I go through the order I want, I TAB it, and it works but once it reaches the last box then it takes 3-4 times more tabbing to get to the first field. I tried disabling the TabStop property for the controls I don't want. But I think there might be certain controls that I don't see but they might be included in the Tab property.
My question is that is there any way that I can set the TabStop property of all the controls on the winform to false and then set it to true for the controls I want to include only.
I also open to if there is any other way I can implement this?
If further explanation is needed, let me know!
I have attached a picture thats the order I want and then loop back but somehow its not working. Just in addition there is also two panels in the form and I have disabled their TabStop property to False.
Go to View menu and click Tab Order. This will activate the tab-order selection mode on the form. TabIndex value will be displayed as a number on each control.
Click on controls in order you need them to be tabbed. This will set appropriate values for TabIndex of controls.
After you finished, go to View menu and turn-off Tab Order.
Select controls you don't want to be tabbed and set TabStop = false.
One simple explanation is that you lost a control underneath another one that overlaps it. Or it is located beyond the edges of the Form. A good tool to find it back is View + Other Windows + Document Outline.
If that doesn't help then diagnose it by adding a Label and a Timer. Write the Tick event handler like this:
private void timer1_Tick(object sender, EventArgs e) {
if (this.ActiveControl != null) label1.Text = this.ActiveControl.Name;
}
You should try the following code:
foreach (Control ctrl in this.Controls)
ctrl.TabStop = false;
Also you can try to check the last tabindex. Then go to your form.designers.cs and find all controls with a greater tabindex and then remove them : add
ctrlTabStop = false;
I did not test any of this, so be careful : backup your *.designer.cs before.
Specifically, in my original design, I had Text comments in my ComboBox at load-up time, but then realised that users could type into the box, so I changed the DropDownStyle to DropDownList. Unfortunately, whilst this prevents the user from typing into the box, it also removes the Text from my VS2010 design and also ignores my C# updates to the Text in the program.
Is this normal behaviour or do I have a problem, or do I need to do this via another parameter ?
Keep your DropDownStyle on DropDown.
now on KeyPress event add the following:
e.Handled = true;
Do I programmatically have to manage the backcolor\highlight color on a Listview's item when selected through code?
So if I do this: listView1.Items[1].Selected = true;
Do I also need to do this, so it looks highlight, as it does when selected with a mouse click: listView1.Items[1].BackColor = Color.Blue;
(and clear it when the selection changes)
I would have thought that Selected = true would also do the 'backcolor\highlighting' that happens through the mouse click. Am I missing something?
Has the control got focus? If not the default setting is to hide the selection when the control doesn't have focus - see the HideSelection property.
You do not need to handle the highlighting code yourself, but the item will only appear highlighted if the ListView control has focus. Add listView1.Select() after you select the item and see if that helps.
Otherwise, you'll need to set the HideSelection property on the ListView to false.