The project is based on wp 7.5.
I have a grid, and when the user swipe it, a textbox will reveal and the keyboard will show.
The function is ok, but there is a little bug, when the system keyboard show, it will cover over the textbox, so the user can't see the stuff they have entered.
how to solve it?
It would be best to position such a textbox so that it would not be obscured when the keyboard is shown. This is typically done by placing it at (or near) the top of the page.
Depending on how you've structured your XAML the default behaviour of the phone should scroll the content so that it is not obscured by the keyboard. Without being able to see you code I couldn't say why this isn't happening.
Alternatively you could but the page content inside a ScrollViewer and manually scroll it so that the TextBox is visible when it has focus.
Related
I have a WPF RichTextBox in my application that sits in Grid. It gets updated every second or two as it displays logs (though sometimes there are no logs for up to a minute depending on the load).
The grid is not always visible, as it sits in its own tab. If the user is on another tab, the logger is not visible.
My problem is that I want the RichTextBox to scroll to the end every time a new paragraph is added. It seemed simple as there is a 'ScrollToEnd' method on the RichTextBox control and so I call that method every time text is added to the control.
The problem is that that method only works if the control is visible, if the user is on another tab, the RichTextBox will not scroll to the end and it looks weird when you click on the tab with the logger and after a couple of seconds or longer it scrolls to the bottom when it should already be at the bottom.
Is there a way around this annoying "feature" of the control? I would like to ALWAYS have the RichTextBox be at the bottom unless the user is manually taking control of the scroll bar.
Thanks!
By default, the TabControl actually doesn't change its contents visibility, it removes them from the view completely when you change tabs and then "re-attachs" them when you navigate back to the previous tab.
That's why the Visibility change doesn't get fired. Instead, you should handle the Loaded event, which should get fired right before the view is re-rendered.
Is there a reason you cannot simply call ScrollToEnd in response to the text box becoming visible? That seems like the simplest approach. Did you try it and run into an issue?
Edit: If you are using a TabControl, each TabItem has an IsSelected property you can bind to from the ItemContainerStyle. You could probably scroll your text box in response to the tab becoming selected.
As a separate note: if you are planning to make a custom control for this, here are some things to consider.
I wrote an auto-scrolling version of a FlowDocumentScrollViewer. (I never needed a RichTextBox specifically, but they display similar content.) I can tell you that there are a lot of things to account for, such as knowing when and when not to auto-scroll based on what the user is currently doing.
For example:
If the user takes over the scrolling themselves via the scrollbar or mousewheel, you don't want the control to fight with them.
If they start selecting text, you don't want to scroll it away from them mid selection.
If they scroll to the bottom, you probably want it to start auto-scrolling again.
Also, determining what the user is doing to begin with can sometimes be a complex process on its own.
If I catch mouse move/mouse button down events in one control, how do I route the caught event to another control?
In MSDIN documentation I found WPF UIElement.RaiseEvent but it seems it doesn't exist in Silverlight.
The reason for this question is the following issue.
I have an application where user is able to pick a control on the screen to retrieve control's ID (a custom property). While user picks a control, I don't want default actions of the control to be triggered - no button clicks, no text highlighting, no link navigation etc. That's why when entering the "picking mode", I put a transparent overlay over my application and after user clicks on it I find the element behind the overlay, get its ID and remove the overlay.
This approach is working fine except one scenario when there is a scroll viewer on the screen and user might want to pick an element which is scrolled out of view. Thus when picking elements, user at first clicks on a scrollbar to scroll the required element into view, but the scrollbar doesn't work because its behind the overlay.
Currently I have working code which detects if the element under mouse cursor (and behind the overlay) is a scrollbar instance, and thus I ignore it for my picking process - my application doesn't require picking scrollbars. But how do I pass the mouse event from the overlay to the scrollbar behind?
The short answer is, you can't route the mouse events.
But what you can do is: as long as the mouse is hovered over a Scrollbar you can set the IsHitTestVisible property of your mouseClick catcher overlay to false. The click will just go through it. Or can you only detect the Scrollbar the moment the user clicks?
I have some simple code for popping up a "dialog"-like thing over part of my application window. The idea is, the user must dismiss the dialog before continuing to work with that part of the page.
This works by hovering a large semi-transparent rectangle over the part of the page that is supposed to be disabled - which does a nice enough job of blocking clicks to the region. You see this sort of thing a lot in WPF and Web apps, I think.
The problem I have is, the user can still reach all those juicy blocked controls by tabbing to them using the keyboard. "No problem", I hear you say, "just set the IsEnabled on the panel to false, thereby blocking keyboard access".
Unfortunately, disabling the controls:
Doesn't look very nice
Tends to have unintended consequences with custom styles and bindings further down the tree
So, is there a better way to disable a part of the page, without setting the "IsEnabled" property, such that it doesn't change the visual appearance of any of the controls?
Thanks,
Mark
Can you put your "dialog" XAML in a popup window? Then, call ShowDialog() on the window to make it a modal window? If you don't want your popup to look like a standard window, you could always syle it to remove borders, etc.
I solved this by subscribing to the PreviewGotKeyboardFocus event, from the parent element in the tree, and then handling the event such that focus never gets passed to the children.
Also, I had to explicitly remove focus from the "disabled" controls as well, of course.
Literally, I want to know that.
In some case, .Focus() appear better than SetFocusedElement(). But another case, it's reversal. So I must know what's different things are there.
Additionally, by MSDN, .Focus() is for keyboard focus, and SetFocusedElement is for logical focus. But I can't feel different thing between logical focus and keyboard focus.
The keyboard focus is generally easier to understand, as that is effectively the control that would receive keyboard input if the user typed. So if you click in a TextBox it will receive keyboard focus and you can start typing. Other controls have other behaviors and may not really support the keyboard, but they can still get the keyboard focus.
For logical focus, your application can be made up of several parts. For example, most applications would have a ToolBar/Ribbon at the top and then their main content below. Now, imagine that your content is a TextBox that currently has the keyboard focus. When you click in a ToolBar/Ribbon control, the keyboard focus is moved to that control. But you really want to "remember" that the TextBox in your content had the keyboard focus before.
To achieve this the ToolBar/Ribbon will create new "focus scope". So when you click in the ToolBar/Ribbon control, you move the keyboard focus but the TextBox still has the logical focus for the window. That allows the TextBox to be given the keyboard focus back when the user is done working with the ToolBar/Ribbon.
The same holds true if you interact with another application, as your application doesn't have the keyboard focus. When you go back to working in your application, it uses the logical focus to know who had keyboard focus last (and should have it restored).
Using FocusManager.SetFocusedElement(), you can specify a UserControl of which you want to set focus on an element. So you can set focus on a control that is in a different part of your program.
Control.Focus() is just straightforward, you set focus on the said control (which is more intuitive).
Wild guess: you use FocusManager.SetFocusedElement() improperly, resulting in unwanted behaviors but bottom line, it's the same thing really.
Sidenote: "logical" focus and "keyboard" focus are 2 different things in WPF.
On C# winforms project, I have a small table, a filter box, an Add button and a Done button grouped together, and they all fit together within 250x250 pixels. I only need to show these elements to the user when they press a button. I figured this could be done using a pop up modal screen or by making room on the main screen until the user presses the Done button.
I know a disadvantage to modal screens is that they can cause problems for users when/if they lose track of the modal screen and then they think the program's not responding.
The disadvantage I see for using a dynamic main screen is that the reshaping interferes with the overall layout. But maybe I could find a way to overcome that problem.
I'm new to all of this, so I wanted to ask opinions here. Thanks.
Put them all on a panel (or, even better, a custom control), style it to look nice, and then only show the panel on button click.
If you put them in a groupBox or FlowLayout panel possibly in the corner of the main screen and then set the visibility or even enabled on the entire control when they can or can't press the buttons works well.
disable until time they can edit.
groubB.enabled = true;
or
groubB.Visible = true;
When the user clicks the button, could you disable all of the controls in the main form and then place the panel in the center of the main form, on top of the other controls? Maybe make the panel a little larger with some decoration around it for emphasis. Then, when the user clicks 'done,' dismiss the panel and re-enable all of the controls in the main form.