navigate to link in xps document using wpf - wpf

I am trying to open an xps document in wpf with vb as a fixed document with documentviewer, then navigate to a bookmark/link within the document. I have unpacked the xps and found the available links in DocStucture.struct, but I don't know how to tell the documentviewer to go to the link's location. The documentviewer is contained within a Frame in a window and I can click on a link in the document's table of contents to the different links. The purpose is to allow the end user to open the document to a specific location when he/she pushes a button (the document is a user guide).
Can someone explain how to do this?
Thanks!
edit:
I have tried packing the link into a uri, however I can only figure out how to make the frame navigate to a uri not the documentviewer:
class for the window that contains the user manual:
Partial Public Class UserManual
Private Sub DocViewer_Loaded(ByVal sender as Object, ByVal e as System.Windows.RoutedEventArgs)
Dim documentName As String = "#.\User Manual.xps"
Dim xpsDoc As XpsDocument
xpsDoc = New XpsDocument(documentName, IO.FileAccess.Read)
DocViewer.Document = xpsDoc.GetFixedDocumentSequence
End Sub
Public Sub New()
MyBase.New()
Me.InitializeComponent()
End Sub
End Class
in the main window from which the user manual will be opened:
Private Sub Button_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)
Dim UserManualWindow As UserManual = New UserManual
UserManualWindow.Show()
Dim uri = New Uri("pack://file:,,,/User Manual.xps#PG_8_LNK_94")
UserManualWindow.DocFrame.Navigate(uri)
End Sub
This doesn't work. The frame just shows the text of the uri. I can't find a similar method of the documentviewer. The gotopage method only takes in a page number, not a link.

So I managed to work through it and learned that I was close. Instead of commanding the frame to navigate to the uri, I just needed to set the frame's source:
UserManualWindow.DocFrame.Source = uri
Now the frame updates to the correct fragment within the xps document.

Related

host WPF windows in another WPF window

here is my problem: i have created a main window called mainWindow in XAML (vb.net) and inside i have 2 buttons (valid and stop) and a grid in the center.
I have two others little windows (valid window and stop window) written in XAML (vb.net) which have buttons, textbox...
I want, when i click on valid button or stop button, display the valid window or the stop window inside the grid of my mainWindow, so i have this code in my mainWindow.vb:
enter code here
Private Sub valid_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles valid.Click
Dim content As Object = valid_.Content /*Classe valid_ (a window in xaml)*/
valid_.Content = Nothing
Me.Grid.Children.Add(content)
End Sub
Private Sub stop_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles stop.Click
Dim content As Object = stop_.Content
stop_.Content = Nothing
Me.Grid.Children.Add(content)
End Sub
So when i click on button valid in my mainWindow, it's ok it displays the valid window in my grid.
First problem: then when i click on button stop in my mainWindow, the stop window is placed just above the valid window, it is not nice, is there a way to clear the grid before display this second window?
And finally, the biggest problem: i need to click many times on valid button or stop button but when i click the second time i have a null reference exception: Me.Grid.Children.Add(content) content is null after the first call so i am only able to click one time on my button.
How can i fix it in order to click many times on my buttons please?
I give you thanks.
Yet again, someone writes some invalid code and then says why isn't this code working? If you look at your code, you should see something:
Private Sub valid_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles valid.Click
Dim content As Object = valid_.Content /*Classe valid_ (a window in xaml)*/
Me.Grid.Children.Add(content)
End Sub
I'm guessing that you have a private variable for your Valid Window as you call it: valid. On this line, what are you doing to your variable?:
valid_.Content = Nothing
That's right! You're setting its Content property to null. Therefore, I'm not really sure why you were surprised that it was null after the first attempt.
How can i fix it in order to click many times on my buttons please?
Try removing the line that sets the Content property to null.
UPDATE >>>
Your problem is really caused by the fact that you cannot display any UI element in two places at once. Your whole idea of copying the Window.Content to your DataGrid is entirely wrong, but in the name of brevity, your fix is simply to move your content back to the Window, rather than setting it to null each time. Try something like this:
Private Sub valid_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles valid.Click
If Me.Grid.Children.Count > 0 Then 'Put content back where it belongs
Dim oldContent = Me.Grid.Children(0)
stop.Content = oldContent
Me.Grid.Children.Remove(oldContent)
EndIf
Dim content As Object = valid_.Content /*Classe valid_ (a window in xaml)*/
valid_.Content = Nothing
Me.Grid.Children.Add(content)
End Sub
Please forgive any code mistakes, as I don't write VB.NET. Also, you'll need to update your other method likewise.

Open User Control from user control in main window grid WPF

Maybe first I will tell about my application.
When for example an employee will log into my application, he will have loaded "Employee Menu":
Dim Empl As New Employee
MainGrid.Children.Add(Empl)
Grid.SetRow(Empl, 1)
This is from Window_Loaded event. Menu is User Control, and there I have few buttons to open and operate another user controls. When I press for example button "Question":
Public Class Employee
Dim mw As New MainWindow
Private Sub btnQuestionAdd_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnQuestionAdd.Click
Dim Que As New QuestionAdd
mw.MainGrid.Children.Add(Que)
Grid.SetRow(Que, 2)
Grid.SetColumn(Que, 1)
End Sub
End Class
I don't know why nothing is loading after button_click.....
Is it so hard to navigate main windows grid from other controls?
This is just a guess as you've not provided much information, but I noticed the following issue which may be the culprit.
In your first code snippet, you seem to be creating the employee from the MainForm:
Dim Empl As New Employee
MainGrid.Children.Add(Empl)
Grid.SetRow(Empl, 1)
Your following comment would seem to confirm that assumption:
This is from Window_Loaded event. Menu is User Control, and there I have few buttons to open and operate another user controls. When I press for example button "Question"
And yet, in your Employee class, you are creating a brand new instance of MainWindow and then adding data to it:
Public Class Employee
Dim mw As New MainWindow
Private Sub btnQuestionAdd_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnQuestionAdd.Click
Dim Que As New QuestionAdd
mw.MainGrid.Children.Add(Que)
Grid.SetRow(Que, 2)
Grid.SetColumn(Que, 1)
End Sub
End Class
If this observation is correct, then I think you need to go back to the books and understand the concept of classes and instances.
You essentially created a second form (which is hidden because you never explicitly show it) and then modify this second form rather than the original. To prove this hypothesis, try adding the following line of code:
Public Class Employee
Dim mw As New MainWindow
Private Sub btnQuestionAdd_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnQuestionAdd.Click
Dim Que As New QuestionAdd
mw.MainGrid.Children.Add(Que)
Grid.SetRow(Que, 2)
Grid.SetColumn(Que, 1)
mw.Show() ' <---
End Sub
End Class
You'll likely see a second form pop up with all of the changes your were expecting on your first form.
As to how to fix this, the easiest path is going to be adding a parameter to your initializer ("Sub New") which accepts the MainForm as a value. You can then assign the value to a field or property (probably just your mw field) and continue on your merry way. This is going to give you headaches down the road, though, so it might be a good time to start learning more about software architecture, especially the concept of separation of concerns.

Is there a way to tell the Wiinforms WebBrowser control to use the current browser to open a hyperlink in?

I have a winforms application with a web browser control. I am wondering if there is a way to tell the browser control to open a URL in the current active browser, regardless of whether or not it is the default browser. My gut instinct is that this simply isn't feasible, as this control is utilizing the operating system's default browser as defined by the user.
use:
System.Diagnostics.Process.Start()
or just try this one:
Private Sub WebBrowser1_NewWindow(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles WebBrowser1.NewWindow
Dim myElement As HtmlElement = WebBrowser1.Document.ActiveElement
Dim target As String = myElement.GetAttribute("href")
Dim newInstance As New Form1
newInstance.Show()
newInstance.WebBrowser1.Navigate(target)
e.Cancel = True
End Sub

Only one windows should be open at once in WPF?

I am developing a WPF project in vb.net and have multiple windows in it. When user selects a menu item a new windows opens and the problem is when the user clicks on other menu item the current window should close by itself.
How do i achieve it?
Thanks!
I think you mean this based upon your comment:
Class MainWindow
Public Win3 As Window3 = New Window3()
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
Win3.Show()
Me.Close()
End Sub
End Class
There are two ways to do this:
If the menu items share the same form then in the form create a subroutine, that you call instead of new, that checks if it is already shown/created and if not opens (as you already have). If it is open reload with the new information.
Otherwise before opening the new form go though the open forms (shown below from this website in C#):
FormCollection fc = Application.OpenForms;
foreach (Form frm in fc) {
//iterate through
}
For each form check if it's name is equal to one of the menu items and if it is close it (after saving if required). Then after you exit the for loop you open the new menu item.

WPF navigation via buttons

Question: Is there a way to make a button behave like a hyperlink inside of a user control?
I've been searching around for a few days now and haven't found anyone who has addressed this. How do you use a button to navigate in a WPF application? Specifically how do you make a button inside of a user control navigate it's host frame? Bare in mind that User controls do not have direct access to the host frame. so simply:
this.NavigationService.Navigate(new Uri(this.addressTextBox.Text));
won't work. I'm using user controls. If you are using only pages, this is the answer you are looking for, if you are using UserControls, look at my answer below.
I feel like a goof ball for answering my own question, but i figured it out at long last!
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
Dim pg As Page = CType(GetDependencyObjectFromVisualTree(Me, GetType(Page)), Page)
Dim newPage As %desired uri here% = New %desired uri here%
pg.NavigationService.Navigate(newPage)
End Sub
Private Function GetDependencyObjectFromVisualTree(ByVal startObject As DependencyObject, ByVal type As Type) As DependencyObject
'Walk the visual tree to get the parent(ItemsControl)
'of this control
Dim parent As DependencyObject = startObject
While (Not (parent) Is Nothing)
If type.IsInstanceOfType(parent) Then
Exit While
Else
parent = VisualTreeHelper.GetParent(parent)
End If
End While
Return parent
End Function
This function i found here (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/f8b02888-7e1f-42f4-83e5-448f2af3d207) will allow for the use of NavigationService inside of a user control.
~N
Use the NavigationService..::.Navigate Method:
void goButton_Click(object sender, RoutedEventArgs e)
{
this.NavigationService.Navigate(new Uri(this.addressTextBox.Text));
}

Resources