Visual Studio is not letting me add CefSharpBrowserControl to a form via the designer - vb.net

So I decided to try out the CefSharp extension, and what's the first thing I encounter? An error that doesn't let me use the add-on.
This is ridiculously frustrating because I've done every single thing even the administrator or creator has said to do on any forum I've been on. I tried to just compile the source code on the CEFSharp's GitHub, but that didn't work.
If I'm brutally honest, I think that they should just provide a pre-compiled .dll file or group of .dll files that you can just add to the references, instead of just expecting you to do it yourself. It's just a pain, CEFSharp.
I've tried putting the Configuration to x64 AND Any CPU. I've tried making references to several different dlls associated to CEFSharp. I've tried to add the browser element programmatically, and that's worked, but I can't do anything with it (such as execute code when the webpage is done loading). So far none of these solutions have worked at all.
Imports CefSharp
Imports CefSharp.WinForms
Public Class Browser
Dim browser As New _
CefSharp.WinForms.ChromiumWebBrowser("https://google.com/")
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles _
MyBase.Load
Me.Controls.Add(browser)
browser.Parent = Panel1
browser.Dock = DockStyle.Fill
End Sub
End Class
Any time I want to add the browser control to my form via the designer toolbox, it won't let me. It keeps showing this error box that says "Failed to load CefSharpBrowser, deleting from the toolbox." Or something along those lines. It's supposed to just be able to drop into the designer, but it's obviously not.

There are similar discussions on CefSharp's google group: Adding CefSharp control to the toolbox and The name "WebView" does not exist in the namespace.
They say that Visual Studio has some limitations when using a mixed mode (C++/CLR) assembly. There is no Visual Studio designer support out of the box in CefSharp. There is some hack about how to do it, but I do not think it worth it to even spend time on it. Most people just accept the fact and move on.
We successfully use CefSharp for one of our projects and we add ChromiumWebBrowser control to a form programmatically, very similar to how you did it in your sample.
I've tried to add the browser element programmatically, and that's
worked, but I can't do anything with it (such as execute code when the
webpage is done loading). So far none of these solutions have worked
at all.
There is a LoadingStateChanged event which you can use to monitor the status of a web browser control. We use it to show progress indication until our web page is fully loaded. Here is how we do it:
private System.Windows.Forms.PictureBox picProgress;
bool loaded = false;
ChromiumWebBrowser browse;
public Main()
{
var uiUrl = "some url or local html file";
browse = new ChromiumWebBrowser(uiUrl);
browse.Dock = DockStyle.Fill;
Controls.Add(browse);
browse.LoadingStateChanged += Browse_LoadingStateChanged;
}
private void Browse_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
{
if (!e.IsLoading)
{
picProgress.BeginInvoke((Action)(() => {
loaded = true;
picProgress.Visible = false;
browse.Visible = true;
}));
}
else
{
browse.BeginInvoke((Action)(() => {
loaded = false;
browse.Visible = false;
}));
}
}
Sorry, it is in C#, but I think you can easily adapt it for VB.net.

Related

UWP SyncFusion SfDataGrid Serialization Exception

I'm trying to make use of the SfDataGrid component in my UWP app and have everything working just fine in debug mode. When I switched over to release mode to regression test the app before publishing to the Windows store the app throws an exception during grid serialization.
I have an SfDataGrid defined with 4 text columns, 1 numeric column and 1 template column. The template column just includes a delete button so that the user to can remove the row.
I have a method to return the serialization options as follows:
private SerializationOptions GetGridSerializationOptions()
{
return new SerializationOptions
{
SerializeFiltering = false,
SerializeColumns = true,
SerializeGrouping = true,
SerializeSorting = true,
SerializeTableSummaries = true,
SerializeCaptionSummary = true,
SerializeGroupSummaries = true,
SerializeStackedHeaders = true
};
}
Then I have another method to serialize the grid settings as follows:
private void RetrieveDefaultGridSettings()
{
using (MemoryStream ms = new MemoryStream())
{
gridReport.Serialize(ms, GetGridSerializationOptions());
_defaultGridSettings = Convert.ToBase64String(ms.ToArray());
}
}
I've followed the SyncFusion documentation (https://help.syncfusion.com/uwp/datagrid/serialization-and-deserialization) which describes how to serialize template columns. I have everything working perfectly in debug mode, but when I switch to release mode I get an exception on this line:
gridReport.Serialize(ms, GetGridSerializationOptions());
The exception is:
System.Runtime.Serialization.InvalidDataContractException: 'KnownTypeAttribute attribute on type 'Syncfusion.UI.Xaml.Grid.SerializableGridColumn' specifies a method named 'KnownTypes' to provide known types. Static method 'KnownTypes()' was not found on this type. Ensure that the method exists and is marked as static.'
I've had a look at the SerializableGridColumn class and can see a public static method called KnownTypes so I don't really understand why this exception is happening. I'm even more confused about why it's only happening in release mode.
In attempt to fix the problem I have tried referencing the entire SDK, removing the SDK and referencing the specific assemblies (Syncfusion.SfGrid.UWP, Syncfusion.Data.UWP, Syncfusion.SfInput.UWP, Syncfusion.SfShared.UWP, Syncfusion.SfGridConverter.UWP, Syncfusion.XlsIO.UWP and Syncfusion.Pdf.UWP) but neither yields a different result and the exception still occurs, but only in release mode.
Switching off the setting "Compile with .NET Native tool chain" does resolve the problem, but is not a practical solution as this blocks me from publishing the app to the Windows store.
Thanks very much for any assistance anyone can provide.
After exhausting all possible problems with my own code, I logged with an issue with SyncFusion. They're investigating and will hopefully provide a fix soon.

Extend Office JavaScript API with own Browser Control

I'm trying to write a VSTO-Add-In with a System.Windows.Forms.WebBrowser-Control enabling something similar to the Office-JS-Add-In model.
The WebBrowser-control would show some HTML/JS-Page and be able to call C#-functions in the VSTO-Add-In from JavaScript via window.external and the ObjectForScripting-property of the WebBrowser-object.
That is in JS the call would be
window.external.DoFancyStuffToMyDocument(withTheseParams)
while there had to be some
class MyFunctionProxy() {
public void DoFancyStuffToMyDocument(string theParam) {
//code here
}
}
in the C#-Code an this would be attached to the WebBrowser
myWebBrowser.ObjectForScripting = new MyFunctionProxy();
So far so good. Now comes the catch. I want my HTML/JS-Code be able to also utilize the office.js code and functions like
Word.run(function (context) {
var thisDocument = context.document;
var range = thisDocument.getSelection();
range.insertText('"Hitch your wagon to a star."\n', Word.InsertLocation.replace);
//...
}
Does anyone see a way of getting this to work?
My initial guess was that the OfficeJS-taskpane-add-ins in Word on-prem use some some similar methode as above with a class derived from WebBrowser and the appropriate ObjectForScripting. This would then suggest that there must be a (hopefully accessible) class which is assigned to the ObjectForScripting-property handling the function calls from office.js. Then I could proxy this ObjectForScripting-class and add my own functions like 'DoFancyStuffToMyDocument()'.

Disable WebBrowser caching

I am new here and really want your help.
I've been trying to disable my webbrowser's cache but I get overload resolution failed because no accessible "Navigate" without a narrowing conversion. I'm stuck and I don't know what to do anymore, I did search all the possible solutions but found no answer.
Here's my code:
Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
Const navNoReadFromCache As Long = 4
Const navNoHistory As Long = 2
Const navNoWriteToCache As Long = 8
Dim navflags As Long
navflags = navNoHistory + navNoWriteToCache
WebBrowser1.Navigate("url", 4)
End Sub
End Class
Original Error message is:
Error 2 Overload resolution failed because no accessible 'Navigate' can be called without a narrowing conversion:
'Public Sub Navigate(urlString As String, newWindow As Boolean)': Argument matching parameter 'newWindow' narrows from 'Integer' to 'Boolean'.
'Public Sub Navigate(urlString As String, targetFrameName As String)': Argument matching parameter 'targetFrameName' narrows from 'Integer' to 'String'.
.NET WebBrowserControl doesn't have overload what accept int or long argument.
So, you can't set BrowserNavConstants (this for IWebBrowser2 not .NET WebBrowserControl) value to .NET WebBrowserControl.
I found following page:
http://msdn.microsoft.com/en-us/library/40x214wa%28v=vs.110%29.aspx
The WebBrowser control stores Web pages from recently visited sites in a cache on the local hard disk. Each page can specify an expiration date indicating how long it will remain in the cache. When the control navigates to a page, it saves time by displaying a cached version, if one is available, rather than downloading the page again.
Use the Refresh method to force the WebBrowser control to reload the current page by downloading it, ensuring that the control displays the latest version.
Updated.
I try the code following, that looks like work fine :
private void button1_Click(object sender, EventArgs e) {
webBrowser1.Navigate("http://www.google.co.jp");
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
webBrowser1.Refresh(WebBrowserRefreshOption.Completely);
}
This loads page two times.
So after some time of searching and testing different methods I came with a good result.
Shell("RunDll32.exe InetCpl.cpl, ClearMyTracksByProcess 8", vbHide)
This is the code I used to delete the cache that held my web browser on a blackscreen.
What it does is search for the Internet Explorer's Temporary files and deletes them, the vbHide has to be kept next to the comma to work, what is does is hide the window that pops us telling you it deletes temp files.

How to add webpartzone in sharepoint 2010 programmatically on C#?

I have a really simple question and probably hard answer.
How to add webpartzone into my sharepoint page using C# code?
What I did is: I create visual web part project and added this code to page_init event of it:
protected void Page_Init(object sender, EventArgs e)
{
WebPartZone webPartZone1 = new WebPartZone();
webPartZone1.AllowLayoutChange = true;
webPartZone1.EmptyZoneText = "No Data are provided";
webPartZone1.Enabled = true;
webPartZone1.HeaderText = "My Custom Zone";
webPartZone1.Visible = true;
this.Page.Controls.Add(webPartZone1);
}
and it's doesn't work. but can give you some idea of what I want. I'm really confused.
I think, what you're trying is a bit wrong, you're trying to add a web part zone in a web part. I don't know if it is possible but you can try to create it via code to a master page.
I mean, you will not add the created web part zone control in "this.page" but to its master.

how to save/restore a form and controls between program runs?

I have a complex form to allow the user to configure my app.
What's the best way to save the form state & reload when the program next runs.
I mean text he has entered in list boxes, the selected item of combo/list/radio, whether a checkbox is cheeked, etc
Lots of people here telling me when to save, but not many telling me how ...
In the end I went with WritePrivateProfileString()
You have a few options of where to save the entered settings - in a configuration file, or in the registry, maybe a database (maybe even "the cloud", but i won't go there).
You should have the user carry out a specific action (such as clicking an Apply button) before you save the settings - you shouldn't just save the settings when the user closes the form, as that is ultimately not good UX.
How you persist the settings is totally up to you - you can save them into a straight name/value pair style config file, you may want to use XML in the config file, or you save them as keys and values in a known spot in the registry (or you could save name/value pairs into a database table).
When your application is next run, one of the start up tasks can be to check the known location (whether it be the registry or a config file) for the settings, and then load them into a settings class. Make sure that you have logical default values for each setting in case it has either never been set, or for some reason you cannot read it back in. The settings class can then either be passed in to each form for it to apply whatever settings are relevant, or it could be a static class (globally visible single instance class) so that it can just be read from anywhere in the application.
Edit: after reading your comment to another answer, here is another option, slightly more advanced. Use the settings class i mentioned earlier, but also use binding - you can bind your settings object directly to your form, so any values entered will be updated directly into the settings object without you having to write code to do it (provided you use two way binding). The "streaming" can be achieved by serializing the settings object to a file (or a database), i suggest you look at the XmlSerializer.
Serialize the Form.
Implement ISerializable, and in serializable constructor and GetObject() method load/save your fields.
In OnClosing serialize the form.
///
/// try to obtain the las serialized main form with old data
MainForm mainForm = DeserializeMainForm("mainForm.data");
///
/// if any old data found, create a new(empty) main form
if (mainForm == null) mainForm = new MainForm();
static MainForm DeserializeMainForm(string filePath)
{
MainForm mf = null;
FileStream fileStream = null;
try
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
fileStream = new FileStream(filePath, FileMode.Open);
mf = (MainForm)binaryFormatter.Deserialize(fileStream);
}
catch { }
finally
{
if (fileStream != null)
{
fileStream.Close();
}
}
return mf;
}
MainForm:
[Serializable]
public partial class MainForm : Form, ISerializable
{
protected MainForm(SerializationInfo info, StreamingContext context)
: this()
{
if (info == null)
throw new System.ArgumentNullException("info");
this.tbxServerIp.Text = info.GetString("server ip");
this.tbxServerPort.Text = info.GetString("server port");
this.tbxEventFilter.Text = info.GetString("event filter");
this.tbxWallId.Text = info.GetString("wallId");
foreach (Control control in this.Controls)
{
if (control is EventSender)
{
EventSender eventSender = (control as EventSender);
eventSender.LoadFromSerializationInfo(info);
}
}
}
private void SerializeThis()
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
FileStream fileStream = new FileStream("mainForm.data", FileMode.Create);
try
{
binaryFormatter.Serialize(fileStream, this);
}
catch
{
throw;
}
finally
{
fileStream.Close();
}
}
protected override void OnClosing(CancelEventArgs e)
{
SerializeThis();
base.OnClosing(e);
}
}
Private Sub frm_Closing (sender as Object, e as CancelEventArgs) Handles MyBase.Closing
' save all the values you want'
End Sub
Private Sub frm_Load(sender as Object, e as EventArgs) Handles MyBase.Load
If SaveSettingsExist Then
' restore all the values you want'
End If
End Sub
I actually have a couple of generic routines I use like this for saving the form size/position and ListView column settings. So I have something like...
Private Sub frm_Closing (sender as Object, e as CancelEventArgs) Handles MyBase.Closing
SaveFormPos(Me)
SaveListview(Me, lvuInvoices)
End Sub
Private Sub frm_Load(sender as Object, e as EventArgs) Handles MyBase.Load
RestoreFormPos(Me)
RestoreListview(Me, lvuInvoices)
End Sub
The Me parameter (for the Listview routine) is used to create a key for the values to be saved to the registry. You have all sorts of options in front of you. You could put this functionality into a base class for all your Forms, create a SaveState class, or simply stick routines into a Module. You could save this data to the registry, a database, text files. You could have a generic routine that trawls through the Controls collection looking for TextBoxes, Checkboxes etc.
However, once you've created a useful set of save routines, you can then employ them on any subsequent form you want, so you only need to do the hard work once.
I also agree on having a LoadSettings/SaveSettings set of functions that are called when creating the form/ when closing the application.
As a store location for the application's settings I recommend using the Isolated Storage.
As an addition, depending on the controls you are using on your form, you could have the options of saving their status in XML format format and then restoring it next time.
For example Infragistics controls offer this possibility(e.g UltraDockManager, UltraToolbarManager have a SaveAsXml/LoadFromXml pair of functions).
You can somehow save everything in a hidden textbox in a hidden form.
When the user clicks the apply button, open the text file automatically and make the program read it line by line.
Example:
Line 1 could be the location of an image
Line 2 could be the text for a textbox
Line 3 could be a word or number that the program uses to determine if a
checkbox is true or false