Silverlight issues with InitializeComponent and Databinding - c#

I have some issues with Silverlight issues with InitializeComponent and Databinding. I have a tree structure that, I guess, has to be bound with data directly with the XAML code and that binding is activated when the Main page calls "InitializeComponent".
Here is the rub. The silverlight app has to wait in a call back from a server in order to know what data to load. And this happens in the guts of the C# code long after the initialization has occurred.
So I do not know what to do. It seems only the main page can call InitializeComponent() but I have to wait until I have the data to load and then call InitializeComponent and that happens long after the MainPage is run.

Everything in Silverlight is designed to work with asynchronously loaded data, especially bindings.
You can initialise with bindings to properties that start empty or null. Initialise is all about parsing the Xaml into plain old C# objects (POCOs) to generate a visual tree of controls.
The bindings will update when the data changes so long as the properties make use of INotifyPropertyChanged (i.e. in the parent container that holds your lists/hierarchy) or if they are ObservableCollections they provide change notification about their contents themselves.
If you have a more specific question, please post code sample so we have something to reference.

Related

Notify parent page from child page

I am building an app using UWP and I have MainPage.cs which contains a Frame control where I load different child pages. I would like to pass a listener to the child page to notify my parent page about event that happen in the child. On android I would pass a callback listener which I will have to trigger in the sub-pages so I can get notified in parentl The issue here is that pages are started Frame.Navigate(typeOf(LoginPage)) for which I cannot set a callback since login page is not a referece/object but a type class.
Any help would be greatly appreciated.
It seems like the MainPage is a singleton instance. In such case you could just expose this instance by creating a static MainPage Instance property in MainPage and set it in its constructor. Then you could access MainPage directly from any other page.
The proper solution however would be to use a MVVM framework and instead of communicating between the views directly put the communication within the view models. In MVVM you usually have a sort of navigation service which allows passing parameters/return values and also you can have a event aggregator to raise messages to which other components can subscribe. Good examples of MVVM frameworks are MvvmCross, MvvmLight and Prism. It is definitely worth learning to use and integrate them early on, because it will make your life significantly easier in terms of code maintenance in the long run.

WPF UserControl that is a tab in a tabcontrol - how to detect if it is closing

I have a class that is inheriting from a UserControl. I am showing this class in a WPF TabControl as a tab. The tab has a small x and can be closed by clicking on it. I need a way to do some cleanup code before the tab is destroyed.
I don't believe I can use the Unloaded event to do this because the Unloaded event is called when the UserControl is being destroyed and it is also being called when you click on another tab.
Any ideas on how to deal with this situation?
EDIT:
Here is more info.
In my UserControl class I have a 3rd part control that I am using. Basically a graphing control. There are a couple lines of code I would like to run to ensure that there are no memory leaks. If you want to read more about it then this would be the web address that talks more about it:
http://support.scichart.com/index.php?/News/NewsItem/View/21/wpf-xname-memory-leak--how-to-clear-memory-in-scichart
You can have a look at the way I have done this in the dragablz TabControl on GitHub.
Essentially the TabControl listens to a RoutedCommend raised from the close button, then calls an optional callback which enables a MVVM view model (or old-style control type code) to dispose an associated view model, or perform any other tidy up code you want to do (or indeed cancel the close operation).
In the example project file on GitHub, look for ClosingItemHandlerImpl and work back from there.
http://github.com/ButchersBoy/Dragablz/blob/master/DragablzDemo/BoundExampleModel.cs
ClosingItemHandlerImpl is bound in from the XAML, and the tab control will call it prior to removing a tab.

Why WebBrowser.Document.DomDocument doesn't contain the actual DOM model?

I use WebBrowser.Document.DomDocument and found that it has different DOM model that I can see in IE Debug Tool.
IE Debug Tool contains the valid actual DOM model while WebBrowser.Document.DomDocument doesn't contain some elements added dynamically by JavaScript.
Actually the WebBrowser control displays all elements, even those that were added dynamically, but WebBrowser.Document.DomDocument contains outdated DOM model.
IE Debug Tool can display the actual modified DOM model at it's current state, how to get the current DOM model using WebBrowser component?
There definitively should be a way to do it.
This question could use better documentation. But this is a pretty classic problem, it is a timing issue. You no doubt access the DomDocument property too early, typically you'd do so in the browser's DocumentCompleted event. That's roughly the time the javascript code starts executing. So you'll get the version of the DOM before the changes made by the script.
There's no decent way to deal with the problem. Execution of Javascript is entirely asynchronous and there are no events to indicate any scripting code started or stopped running. The only decent thing you can do is "wait a while", use a timer. Preferably repeatedly until you see a good indication from the DOM that the script is done making its changes.

Wpf MVVM Load UI control asynchronously

I have a mvvm wpf application that loads up a window consisting of many controls in one go. I want this window to load up the controls separately and asynchronously.
Any suggestions?
For that matter, I use a Singleton pattern. If you're familiar with PRISM and its Bootstrapper, it is kinda similar.
The main idea here is to override the method OnStartup in your App.xaml. Default behavior shows in your xaml StartupUri="MainWindow.xaml", you'll have to remove that property.
In the OnStartup override method, I use a class which creates all my objects (Views, ViewModels, link DataContexts... ) and fires an event when initialization is complete.
At this time I dismiss the splashscreen and show a fully loaded app (the InitializeComponent is called when you create your MainWindow, so it'll be already called at this time).
For more extended use, you can add events in your windows and EventHandlers in your bootstrapper class. I use it for example when I want to fully refresh my app (reboot it), and also for database requests (which are, in my case, performed only on application startup to load the referential).
Hope it helped :)
Unfortunately, if your controls are defined in XAML, they're going to be initialized with the InitializeComponent call and go through the loading process. All of the events in loading a XAML window happen whether or not you subscribe to them.
You could add controls dynamically to the form in code behind, but if you have a separate thread do the work, you would need to use the Application Dispatcher CheckAccess and Invoke methods to ensure the controls are loaded on the thread which owns them.

MVVM: How to avoid adding DataContext to Xaml for Blend Support

We have a C# solution that is based on loose Xaml (or Hosted Xaml - have never been to sure of the correct term!). But basically we take a Xaml file and load it into a XamlReader and then pop that FrameworkElement onto a UserControl. We require the ability to handle data binding and we have a ViewModel that takes care of this. However, although I can inject the DataContext through code by setting it on the newly created FrameworkElement, if I want to work easy through Blend and use the built in list of bindable properties when you select the 'Data Binding..." option on a property I need to have set the DataContext right there in the Xaml (if not Blend will add it to the Xaml). I'd rather not have to do this because as I say I am doing this through code already.
The question is - Is there any way to avoid this?
I was thinking of doing this somehow through the app.xaml but the problem is depending on the screen and when it is shown it will have a different context (so we dynamically change the context) and I'm pretty sure you can't load in multiple data contexts.
Maybe there's a better way of splitting this up. Our solution has the following: -
A WPF application with a MainWindow.xaml (the main application)
A User Control in a separate assembly that is placed on the MainWindow.xaml by the main WPF application (above)
This User Control is then bound to the View Model
The main application sets the DataContext as it goes through it's build in state machine.
All Loose Xaml files are held in the main application.
So basically depending on when the state machine displays a screen it will have a different Data Context. The State Machine handles pushing the Data Context and those screens will only work if they are used in the correct context. So we don't really need (or want) to have to set the data context in the Xaml. It done by the state machine.
But I haven't been able to find much info on the Tinterweb around Loose Xaml so we're pretty much learning as we go...
Thanks in advance!
Have you tried d:DataContext={d:DesignInstance ...} ?
It allows you to define a DataContext for design time only, for Blend and VS.

Categories

Resources