Windows Store App Search Contract Blank Screen - vb.net

I recently added the search contract to my app. It is working great! But, whenever I search in the app when it is not running, it only starts with a blank screen. I did the part to add search results even in OnSearchActivated method. But even if I remove the code that I added, the blank screen persists. I created a blank project and added the search contract to it. And it is working in it even when the app is not running. The issue seems to be with my app only. I cannot debug it because it is something that runs when the app is not even running. Tell me a solution.
Code in OnSearchActivated and OnLaunched
Protected Overrides Async Sub OnSearchActivated(args As Windows.ApplicationModel.Activation.SearchActivatedEventArgs)
Dim previousContent As UIElement = Window.Current.Content
Dim frame As Frame = TryCast(previousContent, Frame)
If frame Is Nothing Then
frame = New Frame
Common.SuspensionManager.RegisterFrame(frame, "AppFrame")
If args.PreviousExecutionState = ApplicationExecutionState.Terminated Then
Try
Await Common.SuspensionManager.RestoreAsync()
Catch ex As Common.SuspensionManagerException
End Try
End If
End If
frame.Navigate(GetType(SearchResultsPage1), args.QueryText)
Window.Current.Content = frame
Window.Current.Activate()
End Sub
Protected Overrides Async Sub OnLaunched(args As Windows.ApplicationModel.Activation.LaunchActivatedEventArgs)
AddHandler SearchPane.GetForCurrentView.SuggestionsRequested, AddressOf OnSearchPaneSuggestionsRequested
'Contains definition of arrays ExNam, ExAbbr, ExInst, etc. removed from here to shorten the code and focus on its logic
If rootFrame Is Nothing Then
rootFrame = New Frame()
Train_Thy_Brain.Common.SuspensionManager.RegisterFrame(rootFrame, "appFrame")
If args.PreviousExecutionState = ApplicationExecutionState.Terminated Then
Await Train_Thy_Brain.Common.SuspensionManager.RestoreAsync()
End If
Window.Current.Content = rootFrame
End If
If rootFrame.Content Is Nothing Then
If Not rootFrame.Navigate(GetType(Instructions), args.Arguments) Then
Throw New Exception("Failed to create initial page")
End If
End If
Window.Current.Activate()
End Sub
'Also the namespace definitions are done at the top so they are not the issues neither.

There is a solution to debug your app : in VS2012, Right-click on your project in the Solution Explorer, then go to the Debug tab and in the Start Action section, check "Do not launch, but debug my code when it starts".
Now you can start your app from the Search Contract even if it is not running yet and debug it!
Now for your problem, I would suggest you to check whether the data is loaded before you actually search for something.

You might be hitting the search activation with empty query string. Check your search activation handler, whether you are handling the blank query text case or not?
protected override void OnSearchActivated(SearchActivatedEventArgs args)
{
// your app initialization code here.
Frame frame = (Frame)Window.Current.Content;
if (!string.IsNullOrEmpty(args.QueryText))
{
frame.Navigate(typeof(SearchResultsPage), args.QueryText);
}
else
{
// navigate to your app home page if the query text is empty.
frame.Navigate(typeof(Home), null);
}
Window.Current.Activate();
}

Related

CefSharp SetZoomLevel not working

I am using in a WinForm an object of type:
CefSharp.WinForms.ChromiumWebBrowser
Everything is working fine but I am having an issue when I try to change the ZoomLevel with SetZoomLevel method:
If oBrowser.IsBrowserInitialized Then
oBrowser.SetZoomLevel(-2.0)
Dim frame As CefSharp.IFrame = oBrowser.GetMainFrame
Dim request As CefSharp.IRequest = frame.CreateRequest()
request.Url = url
request.Method = "POST"
request.InitializePostData()
Dim element = request.PostData.CreatePostDataElement()
element.Bytes = postDataBytes
request.PostData.AddElement(element)
request.Headers = headers
frame.LoadRequest(request)
End If
The first time I open the WinForm the Zoom level doesn't change, while it works correctly from the 2nd refresh.
Am I missing some initialization and/or method call... Or do I have to call this method in another position?
Note: the CEFSharp DLL version is 63.0.3.0.
The .NET Framework is 4.5.2
EDITED 01.06.2018: I've found a solution (see below) but now there's another problem: the zoom change is made when the browser is already visible, so it's not nice for the final user to see the page size changing during the form load.
Has anyone a suggestion to freeze the layout during zoom change? Please note that .SuspendLayout() and .ResumeLayout() are not working.
I've found a way to answer my own question. I post it here as it could be useful to other users.
You must add a LoadingStateChanged handler to the ChromiumWebBrowser object:
AddHandler oBrowser.LoadingStateChanged, AddressOf WebBrowserOnLoadingStateChanged
The method would be then something like:
Private Sub WebBrowserOnLoadingStateChanged(ByVal sender As Object, ByVal loadingStateChangedEventArgs As LoadingStateChangedEventArgs)
Dim oBrowser As WinForms.ChromiumWebBrowser = CType(sender, WinForms.ChromiumWebBrowser)
If Not oBrowser.IsLoading Then
oBrowser.SetZoomLevel(-2.0)
End If
End Sub
This solution works good in my environment but now there's another problem: the zoom change is made when the browser is already visible, so it's not nice for the final user to see the Zoom Level changing during the form load.

Unable to navigate backward using hardware key in a Universal App

I navigate forward using Frame.Navigate but when I press the hardware back key on my phone I end up on the start screen and not the page I just visited.
What might be wrong?
The reason behind your problem is, you are creating a Blank Page. If you're creating a blank page, you should define what the app has to do when the back button is fired.
Better, consider adding "Basic page". It will have backstack by nature. If you are navigating from the MainPage to the Basic Page and when you pressed back button at the Basic Page it will back to the MainPage.
I hope this could solve your problem!
If you want to use Blank Page in your application, you need to use like this on your page where you wanna override back button:
add this in your header:
using Windows.Phone.UI.Input;
and then in your constructor:
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
add this anywhere in your code:
void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
this.Frame.Navigate(typeof(MainPage));
e.Handled = true;
}
You've probably forgotten to use the NavigationHelper included in the template of the universal app.
You should use it like this on every page:
NavigationHelper _navigationHelper;
public LoginPage()
{
this.InitializeComponent();
_navigationHelper = new NavigationHelper(this);
}

Check if Form is in bounds of all screens

I'm trying to elaborate if the complete form is visible on screen. To clarify this: I don't care if the form is partially or fully hidden by another form, I just want to know, if the form is completely on the screen.
In Windows it is possible to move forms around, such that they are hidden half way. That is because you can move them past the actual bounds of any monitor. (Further to the left, right or bottom.) How can I check if that is the case in an easy way?
What I figured I could do is to check if the form is in bounds of SystemInformation.VirtualScreen. The problem here is, that not every pixel of the virtual screen is actually visible. Of course this would work if SystemInformation.MonitorCount = 1
Still I'm not really happy with this.
Public Function IsOnScreen(ByVal form As Form) As Boolean
Dim screens() As Screen = Screen.AllScreens
For Each scrn As Screen In screens
Dim formRectangle As Rectangle = New Rectangle(form.Left, form.Top, form.Width, form.Height)
If scrn.WorkingArea.Contains(formRectangle) Then
Return True
End If
Next
Return False
End Function
Best way I can think of is that you check that all four corners of the form are on a screen. Like this:
public bool FormOnScreen(Form frm) {
if (frm.IsHandleCreated) throw new InvalidOperationException();
if (!frm.Visible || frm.WindowState == FormWindowState.Minimized) return false;
return PointVisible(new Point(frm.Left, frm.Top)) &&
PointVisible(new Point(frm.Right, frm.Top)) &&
PointVisible(new Point(frm.Right, frm.Bottom)) &&
PointVisible(new Point(frm.Left, frm.Bottom));
}
private static bool PointVisible(Point p) {
var scr = Screen.FromPoint(p);
return scr.Bounds.Contains(p);
}

MessageBox.Show in App Closing/Deactivated events

I have a MessageBox being shown in Application Closing/Deactivated methods in Windows Phone 7/8 application. It is used to warn the user for active timer being disabled because app is closing. The App Closing/Deactivated events are perfect for this, because putting logic in all application pages would be a killer - too many pages and paths for navigation. This works just fine - message box displays OK in WP7.
I also know for breaking changes in the API of WP8. There it is clearly stated that MessageBox.Show in Activated and Launching will cause exception.
The problem is that in WP8 the message box does not get shown on app closing. Code is executed without exception, but no message appears.
P.S. I've asked this on MS WP Dev forum but obviously no one knew.
Move the msgBox code from the app closing events and into your main page codebehind. Override the on back key press event and place your code there. This is how it was done on 7.x:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
if (MessageBox.Show("Do you want to exit XXXXX?", "Application Closing", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
{
// Cancel default navigation
e.Cancel = true;
}
}
FYI - On WP8 it looks like you have to dispatch the MsgBox Show to a new thread.
This prompts the user before the app ever actually starts to close in the event model. If the user accepts the back key press is allowed to happen, otherwise its canceled. You are not allowed to override the home button press, it must always go immediately to the home screen. You should look into background agents to persist your timer code through suspend / resume.
Register BackKeyPress event on RootFrame.
RootFrame.BackKeyPress += BackKeyPressed;
private void BackKeyPressed(object sender, CancelEventArgs e)
{
var result = (MessageBox.Show("Do you want to exit XXXXX?", "Application Closing", MessageBoxButton.OKCancel));
if (result == MessageBoxResult.Cancel)
{
// Cancel default navigation
e.Cancel = true;
}
}

Getting current Tab/Document in DockPanel Suite

I'm using the DockPanel Suite by Weifen Luo in a little project (webbrowser) and have managed to be able to create tabs and navigate the webbrowser element inside each tab.
But how am I able to change the tabs title/name when the page is navigating to another site?
Basically I just need to get into the current tabs form.
You can get the current tab by using DockPanel's ActiveContent method. For example:
Form myForm = myDockPanel.ActiveContent();
myForm.TabText = "Stack Overflow";
DockPanel.ActiveDocument and DockPanel.ActivePane can also be useful.
After having worked on this a few weeks (not 'till now though :P) I have to say, that this is currently not possible.
You can manage your own (assuming your Document Form is a specific class) by managing:
'FormClosing' and 'Activated' events
'Activated' set your own "active" document to 'this'.
'FormClosing' set your own "active" document to null.
FormClosing is just to catch the case where you are closing the last document. Activated is what manages everything else, like when a new document gets created and is made the active window, etc.
You can use a static global to manage focus. Then access it from anywhere else:
public partial class MyDocument : DockContent
{
public static MyDocument ActiveDocument { get; private set; }
I needed the ability to check which document was active, and set that document to active again after changing some UI elements that automatically reset the active tab, so I used some pieces from here and the DockPanel FAQ, and did some digging to figure out the answer to this problem:
public string GetActive()
{ //Verify if forms that dock in main window are already open
foreach (DockContent form in dockMain.Contents)
{
if (form.DockHandler.Pane.ActiveContent.DockHandler.Form.Name.ToString() == form.Name.ToString())
{
string formName = form.Name.ToString();
return formName;
}
}
return null;
}
And then in some other method you will call:
string activeForm = GetActive();