How can i prevent scrolling up the background image of the page? The rest content should scrolling like always
You can handle the InputPane.Showing and InputPane.Hiding events to override the content scrolling as you'd like. By default, the InputPane will apply a translation to the entire page to keep the focused control in view, but you can handle this yourself for custom behaviour.
For your case, you can find the space the InputPane will take from the OccludedRect property, do the math to figure out how far (if at all) you need to move the page to keep the focused control visible, and apply a transform to a control container rather than to the entire page. Set the EnsuredFocusedElementInView property to indicate that you did the sliding so the InputPane doesn't do its own.
Another option would be to handle Showing and apply an inverse transform just to the image, but it will be trickier to figure out how far the InputPane moved things than it will be to just move them yourself.
Related
I have a custom ZoomBox control based on ScrollableControl which controls its scrollbars through AutoscrollMinSize property.
I would like to be able to handle WM_MOUSEWHEEL events to adjust control's Zoom.
I made necessary steps to make sure that the control receives the mouse events even when it is not in focus, by filtering them on the parent form.
It seems though that the events only reach the OnMouseWheel method if the control does not have its scrollbars active. If it does, it appears that the mousewheel events are being redirected to the scrollbars which handle them (by scrolling).
I would like the scrollbars to be there but only be controlled in a "traditional way", i.e. by dragging the slider or clicking on arrows etc. and handle the wheel myself. Is it possible to achieve that?
Inherit from the ScrollableControl in question and override OnMouseWheel(). In that method don't call base.OnMouseWheel().
As far as I can tell there's no other way to stop ScrollableControl from scrolling if the scroll bars are present.
A side effect is that you will no longer get MouseWheel events. Fixing that is another question. Conceptually you want to call base.base.OnMouseWheel().
I have a custom control that needs to be informed of layout changes from the parent. So if the parent relayouts the child, i want to calculate the new visual position. Unfortunately ArrangeOverride on the child won't get called, which makes sense, because the position doesn't really change inside the child control. Now in the layout pass, my custom control gets properly positioned but the ArrangeOverride is not called.
To give you a clearer picture of what i'm trying to achieve: I have a control, that blurs the background giving an aero glass like effect. To achieve that, my control renders a background control into a visual brush and calculates the viewbox for that brush to make the background shine through, which then is blurred via a blur effect. Its working perfectly fine, as long as the layout doesn't change. If it does, i need to update the brush. And i did this inside the ArrangeOverride method.
So i tried to use ArrangeOverride, MeasureOverride, various combinations of Invalidating or Parent invalidating. At first i inherited from ContentControl but changed that to Decorator, thinking that the Decorator might have some special behavior to no use. I want to avoid LayoutChanged as much as possible because its a very very evil event. I would give you some code, but there is nothing special about it and i think its a rather fundamental problem not really bound to my code. The layouter by the way can be anything(not only canvas).
So what event, methods or ways do i have to get informed of the parent telling my control "I know you didn't changed anything, but i did repositioned you".
So i fixed it in a way i'm not very happy about, but it resolved alot of other unecessary stuff just to make it work, like when the blur control itself is animated. So this solution works now with whatever happens. While i avoided the LayoutUpdated event, i used a similar "evil" event. CompositionTarget.Rendering so in the Loaded event, i register to the rendering event, in the Unloaded i unregister from the rendering event. That way it doesn't matter how often Loaded or Unloaded gets called. In the rendering event itself i just trigger my VisualBrush.Viewbox invalidation code. This works perfectly fine, even if though the event is fired alot. I don't use the blur that much so it doesn't impact the performance so much ... for now.
I'm working on a "tricky" UI. Part of what I need to do is easily show and hide various UserControls. Generally one control will occupy the entire main window when needed, the other's will hide.
In WinForms I used to simply use SendToBack and BringToFront and easily showed the control I wanted to show. Now I have no clue. Played around with zorder but that didn't seem to work.
I'm thinking maybe put all the controls I want on the main window, then pro-grammatically resize them and remove the unused ones... or something.
Any ideas?
You should set the Visibility property to Collapsed, Hidden or Visbible depending on whether you want the controls removed, hidden or shown.
As #AresAvatar points out Collapsed removes the control completely so it takes up no space, this means that other controls may move around the container. If the position of elements is important then using Hidden will be the better option.
UIElement.Visibility Property on MSDN
Visibility Enumeration on MSDN
I am developing a touch screen application and allow users to add touch-based markup to an overlay over content using an ink canvas. I have reached a point where the view behind the overlay has an element that needs the user should be allowed to interact with, but events are captured by the InkCanvas and not by the underlying control. Is there a way to display strokes, but still allow controls behind the InkCanvas to capture events?
You can set InkCanvas.IsHitTestVisible = false and it will still display but you will not be able to interact with it and all events will go to elements lower in the z-order, which sounds like exactly what you want.
In my case I'm toggling the InkCanvas. To accomplish this, I also had to set InkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.None to disable it.
I just wasted my entire evening on something which I thought would be very simple but it seems WPF and Google are letting me down completely.
I need a grid, 6x6 of which I fill every row and column with a custom control. I want to be able to navigate through this grid via the keyboard (I can get those events, no problem) but I cannot seem to find how I can always have the selected grid row/column in the center of my window.
I found some carousel alike implementations, but most of them only work in a single direction and I want two way navigation, yet none seem to support this nor can I extend them to do this.
I essentially want to create a PSP alike grid navigation.
One easy way is to do this:
Create a scrollable form.
Add a 6x6 grid of child controls.
In the GotFocus (or similar) event for all the controls, set the parent form scroll offset to an appropriate position to centre the child.
This is pretty straight-forward thing to implement, with a little bit of maths to work out how to centre the x,y position of a control by setting the scroll offsets (it can be tricky/confusing, but as long as you understand the coordinate systems used for scrolling, not too bad)
Or, another approach that avoids scrolling via the windows APIs and using custom controls:
Create a form
Override OnPaint to draw your grid of 6x6 "controls" as simple graphical shapes or bitmap images centred on the selected "control".
Handle keyboard (KeyDown/Up) and mouse handling (MouseDown/Up) events to make the 36 areas of the graphic respond to user inputs in the way you desire. You'll have to track the selected item and force the window to redraw its graphics to show the new state. Enable double buffering to stop it flickering.
The first approach gives you a lot of windows-based handling for free (tabbing between controls, remembering where the input focus is, and directing events to separate classes for each "control", for example). The second approach strips away all this "help" but gives you complete control over everything, which can often help avoid unintended behaviours (e.g. it won't move the input focus when the user presses Tab unless you specifically write the code to make it do that).