Use a control in MainWindow from a nested page WPF VB.NET - wpf

I have a program in visual basic .net and WPF that uses a series of pages displayed in a Frame control on my main Window, pages are navigated from controls in the main Window outside of the frame and I have all that working ok.
I also have a MediaElement control on that main Window and I need to be able to change the source property of this control from the user clicking on elements in the pages. Every time I have tried to do this so far i have run into an error.
Right now I have a Public Shared function within main Window that is called from the control in the page, the code on the control passes on the URL to be loaded into the source property to the function, then the function is supposed to pass the url into the source property and tell the MediaElement to play.
The error I am getting when trying to achieve this is:
Cannot refer to an instance member of a class from within a shared
method or shared member initializer without an explicit instance of
the class.
Please help, how could I achive this?

Are you getting an instance of the main window or the media element inside of your shared function? If not, this is you problem.
You might stick the media element into a shared variable when the main window is loaded or you can access your main window using the rootvisual of your application.current.app.rootvisual.
If your issue is something else, please post the code in your shared function that causes the error.

Thank you very much Steve for your answer, however I found how to do what I need on another post after idly trying some different search terms today.
Someone known as Jean on another post: https://stackoverflow.com/a/16781963/2668533 suggested something that worked for me, by using application.current.windows:
Dim parent As MainWindow = Application.Current.Windows(0)
parent.player.Source = New Uri(url)
Apologies for seeming such a novice but WPF is completely new to me and I have never encounterd a need for anything similer using WindowsForms.

Related

MVVM Application not Restoring State Correctly

I have built a class library that acts as a GUI framework that can be inherited by other projects. This application is based on projects Wild and Gemini.
My problem is that upon restoring Avalon Dock's layout using the standard serializer
var layoutSerializer = new XmlLayoutSerializer(manager);
where manager is type DockingManager. The manager restores and empty tab. My guess is that Caliburn Micro cannot find the stored ViewModel (named HomeViewModel). However, I am struggling to confirm this.
I believe my bootstrapper to be correct and that the MEF containers are being setup correctly to allow resolution of external types. I have debugged the project to a point where I think this issue is occurring and in the output window I can see Attach(Home) where the attach is occurring (note, "Home" is the display name of the HomeViewModel). However, I don't know what is wrong with the attach process as this is handled by MEF/Caliburn.
I am really stuck with debugging this an wondered if
Any one could offer any insightful advice as to how to proceed with the debugging process?
Anyone would be willing to take a look at the solution?
I have spent a hell of a lot of time debugging this without any luck and the problem is sufficiently esoteric and illusive as to render most posts here irrelevant to me.
Thanks for your time.
as discussed and after looking on the sample code provided, I understand that the following
HomeViewModel or can say LayoutItemBase is not supposed to be reopened as ShouldReopenOnStartup is set to false
if you close the application while leaving a document open for HomeViewModel it is restored on next start with blank view [Not OK]
Analysis
the SaveState method was correctly honoring ShouldReopenOnStartup value and was not emitting the state for the HomeViewModel but dock manager was still emitting an element for the document.
So upon next restart the LoadState does not find any stored state but a window was created as an element was present in the dock manager's layout state
<LayoutDocument Title="HomePP" IsSelected="True" IsLastFocusedDocument="True" ContentId="d716f824-cfff-4b54-8fd6-2d026a99369a" .../>
you did try to use e.Cancel property of Serialization callback to cancel the event, but seems like it is not supposed to prevent of loading a window but just simply to cancel the event if not needed.
Resolution
So the ideal approach is to close the documents which are not supposed to be restored before saving the layout
here is how I did
ShellViewmodel.cs : Line 279 method SaveState(string)
change the following code
if (!item.ShouldReopenOnStartup)
continue;
to
if (!item.ShouldReopenOnStartup)
{
//this item is not supposed to be restored so close the window before saving layout
IDocument doc = item as IDocument;
if (doc != null)
CloseDocument(doc);
continue;
}

How can i retrieve a textbox control's name property from another application's window

I am writing a program that overlay's a toolbar onto another applications window. I am able to iterate through the MDI child windows and even access all the controls via PInvoke. The one thing I am trying to figure out is how to get the controls actual Name property.
I am able to see the name of the field using Hawkeye but I cannot figure out how it is getting the control name.
One thought is that it may be injecting something into the target application and running something like Control.FromHandle but I am not 100% sure.
Thanks for any help.
Unfortunately, the Name property of a control is a property of the .Net object that creates the window not of the control window itself. There is no way to get this value using the window handle - PInvoke or otherwise - from outside of the process.
You would need to do some variation on what Hawkeye appears to do. Attach to the process, examine the object hierarchy and/or inject code dynamically using the CLR Debugging API.

PageFunction OnReturn and the Default PageFunction Constructor

I'm trying to create a Wizard at runtime in VB.NET using the WPF NavigationService and I'm having some problems.
I need to add controls to the PageFunction pages at runtime which seems to involve passing arguments to the PageFunction pages when I create them (prior to navigating to them). This means that the PageFunction pages need to override the default constructor and add arguments to it. This seems to work fine.
The problem is that I also need to call OnReturn once I've navigated beyond the first page (to go back to a previous page) but the OnReturn doesn't work unless I use the default constructor on the PageFunction page it is navigating back to.
The work around I've been considering is creating some global values that the PageFunctions could acssess at runtime in their default constructor but I can't figure out how to define global variables in the MainWindow that the PageFunction pages can get access to.
Any tips or suggestions would be appretiated!
Thanks
Mike
p.s. I can also post my code if that will help.
Since posting my question I discovered that if I set KeepAlive = True on the first PageFunction it solves my problem above

Does calling a ScriptableMember method on a Silverlight control from JavaScript create a new Instance of the control?

I have a Silverlight control with a method named DoSomething() decorated with the <ScriptableMember()> attribute. I then call this method successfully from JavaScript and proved by a little message box that apprears from the SL side that says "Method Called!".
Point is all that works. The problem I am having is that prior to calling this method I build up an ObservableCollection on the Silverlight control containing 1..n FileInfo objects. This works fine too and builds up as I add files to it. Each time I add a file, a messagebox tells me the count from Silverlight (i.e. "Count = 2").
Now the problem: when I call the method DoSomething() from JS and access that ObservableCollection the count = 0! To see what is going on I placed a message in the Silverlight control's constructor to see if it gets entered upon being called from JS, and indeed it does and appears to recreate the control.
If this is the case it kind of makes sense that my ObservableCollection has a count = 0 because it is not the same control instance where I built up the FileInfo collection.
So how in the world do I preserve the collection, and why would simply calling a method exposed to JS from Silverlight, recreate the control and not allow me to access it's given state? I don't want a new control, I need to manipulate it as-is. Or am I off base and doing something else wrong to cause this beahvior?
Thoughts? Thanks!
It turns out the instance registered was the culprit. The MSDN examples show registering a new instance of the type, but in my case I needed the actual instance of the Page Control itself which solved the problem.
So at the completion of my page's initialization, I could register the current page's instance like below:
HtmlPage.RegisterScriptableObject("SLControl", Me)
This allowed me from JS to access the control in it's current state which included all objects in the ObservableCollection as required. I blogged about this topic with code examples and the article below expands on this situation:
Get A Silverlight Control's Current Instance For Communicating Via The HTML Bridge:
http://allen-conway-dotnet.blogspot.com/2012/03/get-silverlight-controls-current.html

Shell StatusBar UserControl communication

I have a wpf main window as the application shell containing status bar and a tab control with two tab items.
I have also two User controls and their View Model objects using MVVM.
I placed each user control on a tab item in the application shell.
My question is, I want the user controls to update the status bar on the main shell. What is the best way to handle that?
Thanks
I have the same question.
I don't know exactly what is the best way to do it but this my guess:
To me, the application class (I mean an override of it) is not right place to put it because it is too central. The status is per Window (Dialog).
Then, you could place it in the model of the Window but it is another bad idea (my opinion) because you will have to modify you model for something very virtual (status).
Personnaly, but I could be really wrong, I decided to declare a method in the parent window directly. Any model, if many, of any of my component that are part of that window could (preferably at initalization time) try to find the method (reflexion) and assign a delegate to it. Whenever you want to update the status you verifiy your delegate is not null and call it if its not. The delegate could be something like: SetStatus(string status). It's not perfect but it seems to respect hi cohesion and low coupling...
Hope it helps.
Eric
BXF (Basic XAML Framework)
http://bxf.codeplex.com/
From the BXF Documentation Page:
In its simplest form, Bxf acts as a message or request router from
application code to a presenter handler.
The idea is that your application code, typically your viewmodel code,
needs to do a set of basic things:
Show views
List item
Show status information

Resources