WPF Web Browser Control with Custom Scrollbar - c#

I'm trying to make a custom scroll bar for Web browser Control.
I used a Scroll Bar Control for this,so i attached Scroll Bar Control to Web browser Control
use following code:
Doc = (mshtml.HTMLDocument)browser.Document;
Doc.parentWindow.document.body.style.overflow = "hidden";
mshtml.IHTMLElement2 ScrolablePlace= (mshtml.IHTMLElement2)Doc.getElementById("ScrolablePlace");
ScrollBar.ViewportSize = browser.ActualHeight;
ScrollBar.Maximum = ScrolablePlace.scrollHeight;
and while scroling scrolbar:
private void ScrollBar_Scroll(object sender, ScrollEventArgs e)
{
if (Doc != null)
{
Doc.parentWindow.scroll(0, (int)e.NewValue);
}
}
this is work,but ScrollBar.Maximum value is always larger than scroll bar place.dose ScrollBar.ViewportSize and ScrollBar.Maximum
set correctly?
I Hope i could explain my problem correctly with this image:

After some research, I've found that a scroll bar maximum property must calculate from this formula :
scrolbar.maximum=(maxsize-scrolbar.ViewportSize)+scrolbar.smallchanges
so i simply do this and it work fine:
ScrollBar.Maximum = ScrolablePlace.scrollHeight- browser.ActualHeight+ScrollBar.SmallChange;

Related

Smooth scrollTo in WebView UWP

scrollTo in WebView UWP may be achieved through:
private string ScrollToTopString = #"window.scrollTo(0,0);";
private async void ButtonClick(object sender, RoutedEventArgs e)
{
await WebViewTest.InvokeScriptAsync("eval", new string[] { ScrollToTopString });
}
But what about animated/Smooth scrolling in WebView UWP? In Android that is achieved either officially or through variations (for example, using android.animation.ObjectAnimator), whereas in UWP only ScrollViewer seems to support it as far as I know. Example 1 Example 2
Any ideas?
You can't animate the WebView because the WebView itself isn't actually scrolling, just like your browser doesn't actually scroll; it's the "window" element that's scrolling.
However, if I understand what you're wanting correctly, just replace your ScrollToTopString with this:
var ScrollToTopString = #"var int = setInterval(function() {
window.scrollBy(0, -5);
if( window.pageYOffset === 0 )
clearInterval(int);
}, 1);";
This will scroll that "window" element I mentioned. You can raise the speed of the interval (I have it set to 1) to slow down the animation, or lower the value of scrollBy to make it go faster.

Customizing default inputs?

I wonder if it's possible to customize my C# application (winforms) to get a better design, I made a PSD (photoshop document) so I can generate png jpeg... pictures if I need them.
Example of a form like the one I want :
Indeed as it was pointed out in the comments, it is easy to use WPF (indows Presentation Foundation) to achieve that result, but if you really need that it must be made in windows forms I can help you with that...
ControlBox and Border
It seens that your form does not have a control box (minimize, maximize and close buttons)
to achieve that you can set
form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None
I'm not sure if that galaxy behind your form is part of the application so i'll be considering that it is not
To achieve that irregular shape of the form we have to do a workaround here
Irregular Shape of the Form
we are going to set a Color to TransparentKey, so everything in the form in that specific color will be transparent, like it does not exists (if you click in that part it will go into de desktop or whatever application you have behind in your form)
So let's use a specific color which we will probably dont use in the form
form.TransparencyKey = Color.FromArgb(111, 111, 111); //You can do it by the editor
So in order to make that white part we are going to use an Panel and a PictureBox outsite of the Panel trying to copy the shape of your image
Stylized Inputs
To make it easier and reusable I'm going to make a userControl in this one
the usercontrol will have
a Panel called HighLightPanel, its dock property will be set to Fill
a Panel called BackColorPanel, it will be inside the HighLightPanel
a PictureBox called InputPicture, its dock property will be set to Left, it will be inside BackColorPanel and its acessor will be public
a TextBox called TextBox, its dock property wil be set to fill, it will be inside BackColorPanel, the BorderStyle Property set to None, you should set the size and font you most desize in this one, I'm going to use Segoe UI; 15,75pt and its acessor will be public
Now we have to make some properties in our UserControl to make it work without work in other controls
First in the SizeChanged event of the HighLightPanel we will make the BackColorPanel be exacly two points smaller in every direction and its position to 1;1 so we can see the HighLightPanel
private void HighlightPanel_SizeChanged(object sender, EventArgs e)
{
this.BackColorPanel.Size = new Size(
HighlightPanel.Width - 2,
HighlightPanel.Height - 2);
}
Now we will create two propertys to handle the Highlight Color
public Color HighlightBorderColor { get; set; }
public Color NonHighlightBorderColor { get; set; }
And in the Enter and Leave Property of our TextBox we are going to change the HighlightPanel
private void TextBox_Enter(object sender, EventArgs e)
{
HighlightPanel.BackColor = HighlightBorderColor;
}
private void TextBox_Leave(object sender, EventArgs e)
{
HighlightPanel.BackColor = NonHighlightBorderColor;
}
So now every time the user enter the Input it will appear that the Input has an Border in the specified Color
Now to enhance its usability to developers we will make some wrappers in its controls to be easier change property of child controls in the editor
public Image InputImage
{
get { return InputPicture.Image; }
set { InputPicture.Image = value; }
}
public PictureBoxSizeMode InputImageLayout
{
get { return InputPicture.SizeMode; }
set { InputPicture.SizeMode = value; }
}
public char PasswordCharacter
{
get { return TextBox.PasswordChar; }
set { TextBox.PasswordChar = value; }
}
public bool ShowInputImage
{
get { return InputPicture.Visible; }
set { InputPicture.Visible = value; }
}
In the InputImage set the picture you want for the User and the Key
Insert the two controls in the position you like
Position of the Form
if you want your form to be moveable without the border you will have to use this snippet, it is more easy in WPF
#region MoveForm
Point LastPoint;
bool ShouldMove;
private void form_MouseDown(object sender, MouseEventArgs e)
{
LastPoint = e.Location;
ShouldMove = true;
this.TransparencyKey = Color.FromArgb(111, 111, 111);
}
private void form_MouseUp(object sender, MouseEventArgs e)
{
ShouldMove = false;
}
private void form_MouseMove(object sender, MouseEventArgs e)
{
if (ShouldMove)
{
this.Location = new Point(
this.Location.X - LastPoint.X + e.X,
this.Location.Y - LastPoint.Y + e.Y);
}
}
#endregion
If you need a lot of special graphics effects learning WPF will indeed be a sound investement.
If all you want is that login screen, it is trivial in Winforms and doesn't take any horrible hacks as you've been told..
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.BackColor = System.Drawing.Color.LavenderBlush;
this.TransparencyKey = System.Drawing.Color.LavenderBlush;
this.ControlBox = false;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Text= "";
These seven lines are all it takes for a form to be transparent. I copied them from the Designer code; you can simply set the 7 Properties in the property grid.
Now add a panel, dock it to the bottom and give it the right color; add a picturebox and your other controls and you are set.
To create the two input groups you also need just a few regular controls and only a few simple lines of code:
You place one Panel, BorderStyle = FixedSingle; and add a Label and a TextBox to it. The Label has AutoSize = False; and both ImageAlign and TextAlign are set to MiddleLeft. You assign an image to the Label's Image and prefix the Text with enough blanks to not overlap. Obviously you should define a PasswordChar for the 2nd TextBox. Now all you need is to script the Enter and Leave events to change the BackColor of the respective Panels between, say SystemColors.Control and SystemColors.MenuHighlight. Size the Labels to almost fill the Panels and you are done. Less code than the WPF version, I'd bet.
If you need such input an controls again and again, simply create Usercontrols for each type you need!
Here is an example of the limits you will hit: Wouldn't it be nice to add a dropshadow effect to the image? It is doable in Winforms. But it would involve painting that effect; this would take at least 15 or 20 lines of involved code instead of simply turning the effect on with (estimated) 1-3 simple lines.
Do you need any nice hover effects? Not easy, to say the least..
These limits will be all over the place, so it really depends on how fancy your requirements will get.
Maybe you should use this example as a starter to compare the two techniques and to warm you up to WPF?

Adding a collapsible panel in outlook

I'm writing an outlook add-in and I'm looking for a way to make a panel docked on the right of my screen collapsible. At the moment the panel is either displayed or removed. You can also scale it but that's not what I'm looking for. I already tried adding 2 buttons which change the width of my panel onclick but the result is that my panel can't get smaller than about 60px in width and the title is still there. Here is the code I use to add my pane:
Microsoft.Office.Tools.CustomTaskPane ctp;
private HistoryPane ctrl;
string title = "Task History";
ctrl = new HistoryPane(mailItem);
ctp = Globals.ThisAddIn.CustomTaskPanes.Add(ctrl, title);
ctp.Visible = true;
ctp.Width = 460;
ctp.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionRight;
Any help to either remove the title, make the panel thinner (about 25px), make it collapsible or all of them would be much appreciated.
here is solution below:
1 - Create a public method in your user control like below:
private Microsoft.Office.Tools.CustomTaskPane _ctp;
public void SetControl(ref Microsoft.Office.Tools.CustomTaskPane ctp)
{
_ctp = ctp;
}
2 - Add any button to Expend and Minimize in your User Control and put below codes on Minimize button on click event:
private void btnMinimize_Click(object sender, EventArgs e)
{
_ctp.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionTop;
_ctp.Height = 50;
}
3 - After your code above use bold line code below:
Microsoft.Office.Tools.CustomTaskPane ctp;
private HistoryPane ctrl;
string title = "Task History";
ctrl = new HistoryPane(mailItem);
ctp = Globals.ThisAddIn.CustomTaskPanes.Add(ctrl, title);
ctp.Visible = true;
ctp.Width = 460;
ctp.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionRight;
ctrl.SetControl(ref ctp);
Hope this will work.

How to access the scrollbar of a webbrowser control in c#?

My webbrowser control has to be disabled (enabled = false) so that the user can't click in it.
This also disables the access to the scrollbar so I'm thinking about creating another scrollbar next to the control that gets and passes its values from and to the webbrowser's scrollbar.
For that, I need to access the webbrowser scrollbar control. How can I find it ?
webbrowser.Controls.Count returns zero.
Hmm I don't know if there is any method to acccess the scrollbar position programmaticly. You can however, scroll by element name:
private void ScrollToElement(String elemName)
{
if (webBrowser1.Document != null)
{
HtmlDocument doc = webBrowser1.Document;
HtmlElementCollection elems = doc.All.GetElementsByName(elemName);
if (elems != null && elems.Count > 0)
{
HtmlElement elem = elems[0];
elem.ScrollIntoView(true);
}
}
}
Also, see this question for other possibilities.
EDIT:
See question Scrolling WebBrowser programatically sometimes doesn't work

Moving panel with directshow video renderer in it

I have a few panels with different directshow IVideoWindow handles bound to them so that the videos get shown inside the panels (WindowStyle properties are: Child,ClipSiblings,ClipChildren,Caption) Now I would like to move these panels around but I can only manage to move them when the video content is not filling the entire panel and I'm clicking+holding mouse button on the empty panel space. I can move the video windows around in the panels but of course they only move inside their respective panel space.
Is there a way to bind the video window content directly to the panel , for example the entire panel with content moves freely around when I click+hold the videowindow menu bar?
Thanks in advance.
Forgot to mention,this is in c#.
I use the Video Mixing Renderer 9 and have it tied to a user control. I have set the VMR9 to Windowless mode and then set the video clipping window on the IVMRWindowlessControl9 interface to the handle of my user control. I also set the video to fill the panel completely, using IVMRWindowlessControl9.GetNativeVideoSize, IVMRWindowlessControl9.SetAspectRatioMode, and IVMRWindowlessControl9.SetVideoPosition whenever the panel gets resized. When the form that contains my user control gets moved around, the video follows along. This is all done with C# and DirectShow.NET.
Edited to add sample code:
public partial class VideoPanel : UserControl
{
private VideoMixingRenderer9 _renderer;
private IVMRWindowlessControl9 _windowlessControl;
public VideoMixingRenderer9 Renderer
{
get
{
return _renderer;
}
set
{
_renderer = value;
if (_renderer != null)
{
var filterConfig = _renderer as IVMRFilterConfig9;
if (filterConfig != null)
{
filterConfig.SetRenderingMode(VMR9Mode.Windowless);
_windowlessControl = _renderer as IVMRWindowlessControl9;
if (_windowlessControl != null)
{
_windowlessControl.SetVideoClippingWindow(Handle);
SetSize();
}
}
}
}
}
private void SetSize()
{
var srcRect = new DsRect();
var dstRect = new DsRect(ClientRectangle);
int arWidth, arHeight;
_windowlessControl.GetNativeVideoSize(out srcRect.right, out srcRect.bottom, out arWidth, out arHeight);
_windowlessControl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox);
_windowlessControl.SetVideoPosition(srcRect, dstRect);
}
}
I solved it finally and I can't believe how silly I was. I left out the
hr = videoWindow.put_MessageDrain(hWin.Handle);
line , of course the videowindow wouldnt "listen" to the panel.

Categories