How can I get the current horizontal and vertical scroll offset of the Web view (showing an arbitrary website)?
I want to save the UI layout and need the offset to be able to restore the viewport position after restarting my application. I´m using WebControl (WPF) with the latest Awesomium.
I found the solution!
Awesomium does not handle anything scroll-related. It´s done by the underlying WebKit. Therefore, I have to use JavaScript to obtain the information:
var xoffset = webControl.ExecuteJavascriptWithResult("window.pageXOffset");
var yoffset = webControl.ExecuteJavascriptWithResult("window.pageYOffset");
And with
webControl.ExecuteJavascript("window.scrollTo(x, y);");
I can apply a scroll offset to the view.
Related
I'm trying to implement a utility for showing throughput over time in a system, and am using Oxyplot to visualise the data.
Currently, zoom and pan are working as expected, but I would like some visual indication to the user which clearly shows whether the graph can be zoomed or panned.
After ditching the idea of using a scroll bar (being neither able to accurately get the position of the visible section of the graph, nor correctly position the thumb of the scroll bar releative to the chart), I have settled on using icons to show whether there is any data on the chart which is hidden to the left or rightmost side.
I would like these icons to work as buttons which allow the user to page left and right on the graph, however as with all things OxyPlot related, the implementation is far more complex than it first seems.
I'm using the WPF implementation, which uses a ViewModel representing the overall data set, with each series item represented by its own model.
This effectively renders almost every tutorial useless as the WPF implementation is significantly different to the basic OxyPlot package.
Currently, the code behind in the view handles the click on the page left/right buttons. I cannot put this in my ViewModel as it must interract directly with the PlotControl object.
private void btnPageRight_Click(object sender, RoutedEventArgs e) {
CategoryAxis axis = (CategoryAxis)PlotControl.ActualModel.Axes[0];
double xAxisMin = axis.ActualMinimum;
double xAxisMax = axis.ActualMaximum;
double visibleSpan = xAxisMax - xAxisMin;
double newMinOffset = xAxisMax + visibleSpan;
PlotControl.Axes[0].Minimum = newMinOffset;
PlotControl.Axes[0].Maximum = newMinOffset + visibleSpan;
PlotControl.ActualModel.InvalidatePlot(true);
}
As it stands, the above code throws no errors, but it does not work either.
If anybody can advise a possible way to make OxyPlot scroll to a given position using just code behind, I would be grateful.
As a last resort, I have pondered trying to simulate a mouse drag event to make this finicky beast behave.
I find the need to work around the problem in that way quite offensive, but desparation leads to odd solutions...
In case anybody else runs into this issue, the following snippet will scroll the graph in pages based on the number of columns visible on the graph at the time.
The snippet takes the number of visible columns as the viewport, and will move the visible area by the viewport size.
Although this applies to the WPF implementation, the only way I could find to make this work was to run this method from the code behind in the View containing the OxyPlot chart.
This should work correctly regardless of the zoom amount at the time.
The CategoryAxis reference must be obtained from the ActualModel as the WPF.Axis does not provide the ActualMinumum and ActualMaximum needed to calculate the viewable area.
The visibleSpan in this case represents the number of columns, with panStep denoting the amount to pan by in pixels.
private void ScrollInPages() {
//To zoom on the X axis.
CategoryAxis axis = (CategoryAxis)PlotControl.ActualModel.Axes[0];
double visibleSpan = axis.ActualMaximum - axis.ActualMinimum;
double panStep = 0;
//Scrolling the chart - comment out as appropriate
//Scroll right one page
panStep = axis.Transform(0 - (axis.Offset + visibleSpan));
//Scroll left one page
panStep = axis.Transform(axis.Offset + visibleSpan);
axis.Pan(panStep);
PlotControl.InvalidateFlag++;
}
I have a line chart, which, after enough data points have been plotted to it, the data will exceed what is visible on screen (so that the chart is only showing the most recent data). When this occurs, I would like a scroll bar to be filled for the X axis, allowing the user to use the scroll bar to view such previous data.
How do I go about doing this? I don't want the user to be able to drag or zoom on the chart itself, just to solely use the scroll bar to navigate along the chart.
I've looked at this article: https://msdn.microsoft.com/en-us/library/dd456730.aspx but it doesn't help & the scrollbars do not appear.
Without seeing the relevant parts of your code it is hard to pin down your problems.
Here is one strange statement:
after enough data points have been plotted to it, the data will exceed
what is visible on screen (so that the chart is only showing the most recent data).
Now this can only happen after you have set the AxisX.Maximum because by default the chart control will squeeze the area more and more while you add points.
But when you have set a maximum of what can be shown, no scrollbar can work or even been shown. Sounds logical, right?
So either don't set it in the first place or clear it when the number of points exceeds what you want to show. To clear it use NaN :
chart1.ChartAreas[0].AxisX.Maximum = Double.NaN;
Or, of course, set it to the last point you want to be shown!
After looking at what you mustn't do let's see what you need to do to show the scrollbar:
First you enable it:
chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
Next you tell it to show only the scrolling handle and not the zoom-reset button:
chart1.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
See MSDN on ScrollBarButtonStyles for the various things the scrollbar can show/do!
And to make sure the user can't zoom set this:
chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = false;
And finally set the current range to show:
chart1.ChartAreas[0].AxisX.ScaleView.Size = 111; // show 111 DataPoints
Now the scrollbar should show.
It is a good idea to study the AxisScaleView class as it has a couple of helpful properties..
Depending on the data type of your X-Values you may also need to set the ScaleView.MinSizeType to whatever suits your data:
chart1.ChartAreas[0].AxisX.ScaleView.MinSizeType = DateTimeIntervalType.Number;
I've been working on a proper slider for my C# WPF project.
I wanted to create a slider, with a background that indicates different parts of the process, by adding a different color to each section on the slider. Furthermore I wanted to add small indicators (like the default ticks, but custom shape and irregular position) to the background.
I achived this by creating a drawing brush and adding correspondingly colored rectangles. This seemed to work fine, but a small distortion was still present, so I investigated further and realized the following:
With slider.ActualWidth I get the width of the whole widget. So in order to create a background covering the actual "slider" part, I'll have to be aware of the distance from the widget to the actual slider. (See image)
I measured the distance in a very small window, in fullscreen and stretched on two screens. It seems this distance is always 5 pixels. I tried google and looked through the info WPF provides on its pages, but either I read over it, or there is no information on this.
Can I be sure this distance is always 5 pixels ? In there any place such information is kept ? Is there maybe another way, to determine the size of the slider itself?
Assuming you haven't tinkered with the Slider template you can just walk down the visual tree and check the ActualWidth of the track:
Border b = VisualTreeHelper.GetChild(slider, 0) as Border;
Grid g = VisualTreeHelper.GetChild(b, 0) as Grid;
Border track = VisualTreeHelper.GetChild(g, 2) as Border;
Console.WriteLine("Track ActualWidth: " + track.ActualWidth);
Is there a way to get a control's absolute screen co-ordinates on Windows Phone? also, will help if that method will work with UserControl components. WPF seems to have Control.PointToScreen, which isb't in the WP APIs
The idea is I'm trying to use a Callout control to point to a UserControl on the screen as a help bubble, and the anchor point doesn't take in absolute coordinates either - so it's a huge connected problem which I'll build up as an answer to this post.
Use UIElement.TransformToVisual()
something like this should do the trick:
var control = this; // assign the control you want to get the position of.
var transform = control.TransformToVisual(Application.Current.RootVisual);
var controlPosition = transform.Transform(new Point(0, 0));
probably you could try Control.MousePosition instead
is this want you want (though it's for WP7): How do you find the screen position of a control in silverlight on WP7?
I am working on a simple Silverlight application. The point of application is to display data loaded from XML file. Data consists of String "password" and Integer "passwordCount". Each loaded position is displayed as a coloured square and whenever user moves mouse over this square it is resized to "passwordCount/10" pixel width or height and the "password" string is displayed on it. Here is an example:
On Mouseover:
Everything works fine if I run it via VisualStudio Run button. The problem is that when I place the script on website, tiles resize in the wrong direction (they become smaller instead of bigger). The text is not displayed either. I don't have the faintest idea why. Silverlight on website opens in a separate window and it looks like that on mouseover:
(source: screenshu.com)
Here is the function I use to animate tiles:
public void rectangle_MouseEnter(object sender, MouseEventArgs e)
{
sbMouseON = new Storyboard();
DoubleAnimation sizeAnimation = new DoubleAnimation();
sizeAnimation.To = passwordCount/10; //passwordCount is always greater than 1000
sizeAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(300));
Storyboard.SetTarget(sizeAnimation, (Rectangle)sender);
Storyboard.SetTargetProperty(sizeAnimation, new PropertyPath(direction));
sbMouseON.Children.Add(sizeAnimation);
Canvas.SetZIndex(rect, 2); //move rectangle up to make animation visible
DrawTextBlock();
sbMouseON.Begin();
}
Mods: Can't Add Comment so posting as answer
Here I am assuming that the "direction" you are passing in the TargetProperty is "(FrameworkElement.Width)" to increase the width of the rectangle.
If so only Logical Reason a Object can reduce in size is "sizeAnimation.To" property you are setting is setting the value which is smaller than the actual width of the object.
What is this DrawTextBlock() doing ? is there any code in there which can change the behavior of animation ?
The problem solved itself. I've just copied all files onto server and it works great. Looks like it was some Windows problem. Thank you for your interest #Abhinav.