How to impelment iPhone like Drag to Scroll Scrollviewer in WPF - wpf

I have a scrollviewer which contains number of buttons and forms. Now I want this application to scroll like in iPhone in touchscreen computers.
I have been trying to modify this tutorial:
Drag scrollable ListView
It implements double click to select the list item. However, I rather wanted to use single click so I changed the following code like this:
// initial source code values
// this registers the double click
isMouseDoubleClick = (e.ClickCount>1);
I changed it to..
// Get initial position of the mouse.
Point initialPos = e.GetPosition(this);
// initialize the isMouseDoubleClick;
isMouseDoubleClick = false
//if the button is pressed and hold (not released yet)..
if (e.ButtonState == MouseButtonState.Pressed) {
// if the hold position is same
if (e.GetPosition(this) == initialPose) {
//if mouse released
if (e.ButtonState == MouseButtonState.Released) {
// set isMouseDoubleClick true;
isMouseDoubleClick = true;
}
}
}
But it does not seems to work.
How does they made it work in iPhone.
The item does not gets selected when touched for a while and also while dragged but it gets selected in a single tap.
How can I make it happen similar in WPF application? A click will select the list item. Click and Hold will not select the list item.

Related

WPF Exiting "Dropped" Combobox, Items no longer editable?

Friends,
I have a WPF Combobox. When the Combobox is opened, I have the items dynamically generated based upon environment variables. So basically a combobox that is bound to a list that is dynamically changing.
Everything works as expected until I Exit the combobox with the dropdown open to enter another control(another combobox).
When I reopen the first combobox, the items appear to be frozen and no longer bound to the list when INDEED the list is changing and is still bound. Its almost like the binding broke.
When this event occurs, I have attempted to forcefully add items, and that doesn't work either. I can see in the code behind that the combobox now contains the additional items, yet it doesn't appear that contain them in the UI.
What is this black magic? Any way to prevent it? is this some type of Stuck focus issue? Maybe the dropdown isn't re-sizing?
I think i have narrowed it down to the physical dropdown is not re-sizing to the new items.
EDIT*
The controls are dynamically generating, so I have no real hard code to show you other than this.
private void CBControl_DropDownOpened(object sender, EventArgs e)
{
((ComboBox)sender).Items.Add("Option");
}
On this event, I will add an items to the combobox, although the items ARE being added to the list, they are not displayed in the UI.
EDIT 2*
I figured it out, so i have 2 comboboxes, it appears that the 2nd was steeling and holding the focus INSIDE the dropdown. (odd bug)
in order to fix it i needed to release it bu changing the index of the 2nd combo box WHILE it is open.
int sel = ComboBoxTwo.SelectedIndex;
ComboBoxTwo.IsDropDownOpen = true;
ComboBoxTwo.SelectedIndex = -1;
ComboBoxTwo.IsDropDownOpen = true;
ComboBoxTwo.SelectedIndex = sel;
and I had to manage the unintended recursive call.
So, here it is.
You got 2 ComboBoxes. If you Open one then directly click into another, the focus is moved to the second combobox dropdown.
If you make any changes to the first combobox, the changes will not take effect to the style(dropdown resize) UNTIL you release the focus from the 2nd combo box dropdown item. Although the items change will take effect, the resize wont.
to release the focus, you need to open the second combox and change the selected index like so:
int sel = ComboBoxTwo.SelectedIndex;
ComboBoxTwo.IsDropDownOpen = true;
ComboBoxTwo.SelectedIndex = -1;
ComboBoxTwo.IsDropDownOpen = true;
ComboBoxTwo.SelectedIndex = sel;
10 hours of debugging. 5 hours of research. First solution I have found. It may be dirty, but its all I can find.

How to detect scroll to top in LongListSelector?

For WP8, I am using LongListSelector to display list of items. I need to detect when the user has scrolled to top to load previous items in the list.
I have tried using ItemRealized event to detect when top element has been realised. There are couple of references where it is used to detect 'scroll to bottom'.
http://rahulpnath.wordpress.com/2013/03/03/windows-phone-series-incremental-loading/#comments
http://code.msdn.microsoft.com/wpapps/TwitterSearch-Windows-b7fc4e5e
But this event gets fired for top element even when that user hasn't yet scrolled to that item. So, that doesn't for me to detect 'scrolling to top'.
Is there any way to detect this?
Use the technique you are already using (ItemRealized), but just ignore the first event (since that's when the list is created. You can ignore it by simply setting a flag:
private bool _firstRealized = false;
void yourLLS_ItemRealized(object sender, ItemRealizationEventArgs e)
{
// do your item detection here. For example:
if (Data[0] == e.Container.Content) {
// then
if (!_firstRealized)
{
_firstRealized = true;
}
else
{
// woo - we've scrolled to top! Do your stuff
}
}
}
You can simply use this reference to get vertical offset
Get vertical offset of LongListSelector
and when vertical offset is 0 (or less than 10) then you are on top ViewPort.

How do I select all the text in a WPF textbox on click

I have several TextBoxes within a UniformGrid.
I want to select all the within a textbox when it is clicked I'd rather the event came from the uniformgrid. I was able to implement selecting all the text with GotKeyboardFocus for when I use only the keyboard with the code below in the handler. However when I merely click on the box it highlights while my mouse is down and on mouse up the cursor appears rather than the text remaining selected.
foreach(TextBox Box in grid.Children)
{
if (Box.IsKeyboardFocusWithin)
{
Box.SelectAll();
e.Handled = true;
break;
}
}
I also have an PreviewKeyUp handler that watches for a max number of letters then moves to the next box. Also each box is initialized with the max number of letters when the screen loads. Which is why I want to do a select all on the text in the textbox so it can be typed over easily.
I was able to use GotMouseCapture almost perfectly except that it doesn't work if you click near the text only near the edge of the textbox.
Try hooking up to the PreviewMouseUp routed event. That worked for me.

Control.Leave Triggered by MouseDown, not MouseUp

I have a C# .NET WinForm. In the form, I allow a user to add an item to a ListView by double-clicking in the ListView. This adds a TextBox control to the ListView and places the key cursor in the TextBox so a user can type.
I detect that a user is done with an item in a couple of ways (e.g. pressing Enter, Esc, Tab...), but also when they Leave (TextBox.Leave) the TextBox.
The problem is this set of steps:
User triggers TextBox.Leave by mousing down outside of the TextBox.
I add the new item to the ListView.
I select the the new item in the ListView.
Mouse up occurs and the new item that I just selected, loses focus and is unselected.
What I would like is for TextBox.Leave to be triggered by MouseUp, not MouseDown. How can I accomplish this?
Edit: Cody suggests using the ListView.LabelEdit property. Here are my results trying that:
listView_DoubleClick(...) {
listView.LabelEdit = true;
if(double clicked on existing listViewItem) {
listViewItem.BeginEdit(); //this works as expected
} else {
var newItem = listView.Items.Add("");
newItem.BeginEdit(); //this doesn't work, see below
}
}
The call to newItem.BeginEdit() only works when the user double clicks where the new item will show up. If they double click on any other blank area in the listview the new item is added, but it does not enter edit mode. What's going on here?
Pressing the mouse down on another control is causing that other control to request the focus and so the focus moving causes the TextBox.Leave event to occur. Preventing ever other possible control from requesting the focus is not a very viable option. But luckly you only need to prevent the ListView from using the MouseDown to shift focus. So you need to override the WndProc of your ListView and when the MouseDown windows message occurs and you are currently showing a TextBox you eat the message. In order words you do not allow the base class to process it.

How do you handle right click on a treeview in WTL/Win32 apps?

I have a basic app written with ATL, using the wizard with VS2008. I have a treeview in the left side of the app. I see how to (painfully) add tree items. Question is how do I show a menu when the mouse is right clicked? How do I trap any click events on each item that could be selected?
You should detect the WM_CONTEXTMENU windows message by specifying a handler in your message map. In the handler you can then show the context menu. You then need to make sure you also handle the menu commands in your message map for when a command is selected from the context menu. Use the COMMAND_HANDLER macro in your message map for this part.
Jeff Yates answer gave me the direction. Since I am using C, the solution is a bit different (and, as usual, a bit more complex):
The idea is to calculate the point in the tree view where the right click was performed, then get the item. Now you can check the type of the item and display the appropriate context menu. To prevent user confusion, the following also selects the right-clicked node in the tree view.
The example assumes there is one tree view in your dialog. You may need to cycle over the tree views in your dialog.
case WM_CONTEXTMENU:
{
RECT rcTree;
HWND hwndTV;
HTREEITEM htvItem;
TVHITTESTINFO htInfo = {0};
long xPos = GET_X_LPARAM(lParam); // x position from message, in screen coordinates
long yPos = GET_Y_LPARAM(lParam); // y position from message, in screen coordinates
hwndTV=GetDlgItem(hDlg, IDC_TREE1); // get the tree view
GetWindowRect(hwndTV,&rcTree); // get its window coordinates
htInfo.pt.x= xPos-rcTree.left; // convert to client coordinates
htInfo.pt.y= yPos-rcTree.top;
if (htvItem=TreeView_HitTest(hwndTV, &htInfo)) { // hit test
TreeView_SelectItem(hwndTV, htvItem); // success; select the item
/* display your context menu */
}
break;
}
The following displays a context menu:
RECT winPos, itemPos;
HMENU hCtxtMenuBar= LoadMenu(ghInst,MAKEINTRESOURCE(ID_CTXTMENUS_RESOURCE));
HMENU hCtxtMenu= GetSubMenu(hCtxtMenuBar, MY_CTXMENU);
TreeView_GetItemRect(hwndTV, htvItem, &itemPos, TRUE);
GetWindowRect(hwndTV, &winPos);
SendMessage (hDlg, WM_COMMAND,
TrackPopupMenuEx(hCtxtMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_NONOTIFY|TPM_RETURNCMD,
winPos.left+itemPos.left, winPos.top+itemPos.bottom, hDlg,0),
(LPARAM)hwndTV);

Resources