I am developing a website that contains a number of "forms" for entering data, etc, and I plan on using Silverlight and RIA Services for managing the data within these forms. The rest of the site will be normal HTML/CSS/JavaScript.
The plan was to create a single Silverlight control with many pages and each page would represent a single form. A HTML page would display this control, but would display a specific page within the Silverlight control.
So, my questions are:
When embedding a Silverlight control within a HTML page how would have the control automatically navigate to a specific page?
After loading a HTML page, and display the Silverlight control, would it be possible to have some JavaScript tell the Silverlight control to navigate to another page?
1 - Silverlight uses URL bookmarks on the end of the URL to emulate navigation.
e.g. http://somesite.com/somepage.aspx#formname
You can also override the default behaviour of the navigation so that it can do cool things like use the bookmark parameter to dynamically specify the name of the Silverlight form you want to show.
2 - You would only need to ensure the bookmark part of your site URLs contain something the Silverlight application can interpret.
Lookup the INavigationContentLoader interface for examples of overriding the navigation with custom behaviour.I found a few articles on the subject quite easily. Try this one.
After a bit of searching I found that the "object" tag that defines the Silverlight control in HTML can have a "initParams" element within it.
So, my thought is each page that I create will only ever have one "form" therefore in the "object" tag I just set "initParams" to define which page the Silverlight control should set as the "RootVisual".
When the control loads the Application_Startup will look at the "initParams" and use that to determine what page it needs to create and assign it to the RootVisual property of the application.
James
1) One of the solutions (not the best one) would be like this:
private void Application_Startup(object sender, StartupEventArgs e)
{
var page = HtmlPage.Document.QueryString["Page"];
RootVisual = GetPage(page);
}
private UIElement GetPage(string page)
{
switch (page)
{
case "page1": return new Page1();
case "page2": return new Page2();
default: return new PageNotFound();
}
}
2) If you want to interact Silverlight control with HTML (JavaScript), then
this is called a 'Silverlight HTML bridge':
HTML Bridge: Interaction Between HTML and Managed Code
Related
I am working on a WPF PRISM application that has the following structure (I have simplified to explain better without additional layers). I am using Unity as my DI/IOC
AppMain - Bootstrapper
Gui - Views and View Models
Data - Data using EF.
In Gui, I have views names as below:
Home
EmployeesView
OrdersView
Reports
I have three regions in the shell.
MainRegion - Main Content
TopRegion - Navigation Menu
BottomRegion - Status Bar
I am using the following method to register views to the regions
IRegion region = _regionManger.Regions[RegionNames.MainRegion];
var mainView = _container.Resolve<Home>();
region.Add(mainView, ViewNames.HomeViewName);
region.Activate(mainView);
The first of activation happens in the Module Initialize method for Top, Main and Bottom.
After this, I am activating other views when the button are clicked. It is just code behind for now. Sample code here:
IRegion region = _regionManger.Regions[RegionNames.MainRegion];
var reportView = region.GetView(ViewNames.ReportsViewName);
if (reportView == null)
{
reportView = _container.Resolve<ReportsView>();
region.Add(reportView, ViewNames.ReportsViewName);
region.Activate(reportView);
}
else
{
region.RequestNavigate(ViewNames.ReportsViewName);
}
PROBLEM1: Any advise on how this can be done or the way I am doing is fine.
The top menu has Home, Employees, Orders, Reports buttons.
In the home page I have recent orders by the employee in datagrid as readonly.
I would like to double click to navigate to the OrderView and pass the selected order to show to the user. PROBLEM2 I am not sure where to do the navigation for this.
PROBLEM3: Another issue was if set the RegionMemberLifeTime keepAlive false, INavigationAware methods don't fire. If I don't set the KeepAlive to false, the page does not get refreshed because, the view model does not get called.
I need the pages to refresh when it is navigated to and not be stale and also handle any confirm prompts to the user when the view is navigated away from it.
Your help is very much appreciated.
it's certainly too late but…
Problem 1/2: is there a particular reason why you add content to region in module initializer?
the common way is more like -> in xaml:
<ContentControl prism:RegionManager.RegionName="MainRegion" />
and in ModuleInit.cs -> Initialize()
_regionManager.RegisterViewWithRegion("MainRegion", () => _container.Resolve<MainView>());
Problem 3:
the view has to implements INavigationAware, IRegionMemberLifetime
and to swich region, in the viewModel you do:
_regionManager.RequestNavigate("RegionWhatever", new Uri("TestView", UriKind.Relative));
But to work you have to register it in ModulInit.cs as an object with viewName, like that:
_container.RegisterType<Object, TestView>("TestView");
and a contentControl with the correct RegionName define in xaml of course
I should create ExtJs4 app, which should have main menu, and each menu item should open a new page with different url, so if the user copies the url and pastes on other browser tab, the app should open that menu item.
I want to use ExtJs's recommended MVC architecture, but I don't know how I can use it with multiple pages/urls. All their examples are using single page.
One option is to reload the page each time when the user clicks on particular menu Item, so every url/menu item/page will be separate ExtJS app with it's MVC. But I think this approach has drawbacks, since the page will be reloaded every time and it's not good for performance. Also it's causes difficulties in reusing of components (common models, stores and views for different pages ).
So I would like to have one single app for all pages, but I don't know is there any solution to have different urls for different views (in my case: for different menu items).
Or is there another approach for such applications?
You would probably want to use a Viewport, and make the Center Region a Container.
The Center Region Container would usually have a Card or Tab layout.
When the user navigates to a new view (Component), you add that view to the Container, and make it active.
The big mistake is to change the URL first. You don't want to do that.
You want to navigate, and then set the URL if the navigation was successful. You should probably not use ExtJS's History component, as it is incorrectly implemented. I would recommend using HTML5 pushState.
You should make sure your navigation system works without changing the URL bar too.
I would recommend reading up on Navigation in Microsoft Prism, WPF, and Silverlight, as there is more documentation there, and then apply that to ExtJS.
http://msdn.microsoft.com/en-us/library/gg430881(v=pandp.40).aspx
Here is an example Navigation process:
call app.requestNavigate('contacts/5'); you would add this yourself.
you parse this fragment to:
navigationContext = {
fragment: 'contacts/5',
xtype: 'contacts-form',
parameters:{
id: 5
}
}
OPTIONAL: If using forms:
get active item from the navigation region (your center region). if exists, call confirmNavigationRequest(callback) . you will need to add this method or event.
if callback(true), proceed with the navigation. this allows the user to cancel a navigation, if say the form is "dirty"
END OPTIONAL
the easy way is to then create a new widget of navigationContext.xtype, add it to the navigation region, then call setActiveItem(widget). destroy the previous active item if it existed.
then call history.pushState(null, null, navigationContext.fragment)
then raise a 'navigatedto' event on the view, passing the context, and you can load the data from there.
More advanced scenarios include:
keep the previous component alive if you expect to return to it. add a keepAlive property and if true, don't destroy when add new components to container.
search the container and ask each component if it wants to handle the current navigation request (for example if a form loaded with contact-5 was already hidden in your navigation region, or if you want to re-use a form)
Like the title said,how may i turn the grid(or page) and the components in it into background gray and unable and show a new component in foreground.
It's a common effect in the web page,but i cannot do that with a xaml.
Please answer in detail better with sample code if you do.Thanks in advance.
Here's an example of using a Popup to display a UserControl when a Page is navigated to. The OnNavigatedTo function creates a popup, binds a Click event to the UserControl, and then shows the UserControl over the entire page. If the correct password is entered, ("password" in the example) the control disappears. You'll need to modify it for your own requirements, but it should definitely get you started.
https://skydrive.live.com/redir.aspx?cid=ef08824b672fb5d8&resid=EF08824B672FB5D8!343
You'll want to use the VisualStateManager and create some animation transitions to switch between the old and new components. I won't paste the code here for brevity, but if you check out:
http://visualstudiomagazine.com/articles/2011/07/22/wcmob_visual-states.aspx
You'll see a simple example of switching between two UI components on a single page within a Windows Phone 7 PhoneApplicationPage. In your scenario, you'd use this paradigm to create 2 animation storyboards, one for showing an overlay control and one for settings the 'disabled' property on the main grid.
How do I show a new form in a Windows Phone 7 App?
I've initialized my class like this:
Jeans jeansform = new Jeans("Elwood Curtis");
However, there's no jeansform.Show() method.
Generally windows phone 7 application use a form navigation similar to a silverlight navigation application hosted by a browser. This allows the phone back button to navigate back from "pages" which have been navigated to.
Your Jeans "form" should actually derive from PhoneApplicationPage and should have a simple default constructor (not one that accepts a parameter as you have at present).
You would then navigate to your page with code like this:-
NavigationService.Navigate(new Uri("/Views/Jeans.xml?name=Elwood%20Curtis"));
Your "Jeans" page then does most of its initial configuration in OnNavigatedTo:-
protected override void OnNavigatedTo(Microsoft.Phone.Navigation.PhoneNavigationEventArgs e)
{
base.OnNavigatedTo(e);
Name = NavigationContext.QueryString["name"];
// Other code you would have otherwise run in a parameterised constructor
}
I'm currently using the WebAii automation framework to write some user interface tests against a Silverlight 3 application. I'm new to Silverlight and suspect that I'm missing some bit of information about the HyperlinkButton.
The application has a HyperlinkButton and I'm attempting to write code that navigates to the page, finds the button the page, then "clicks" that button (which will then navigate to the NavigateUri as specified in the HyperlinkButton's properties).
I can't figure out how to execute that click. The code I have thus far (simplified):
Manager.LaunchNewBrowser(BrowserType.InternetExplorer);
ActiveBrowser.NavigateTo("http://server/appname/");
var slApp = ActiveBrowser.SilverlightApps()[0];
var menu = slApp.FindName<StackPanel>("LinksStackPanel");
var linkicareabout = menu.Find.ByName<HyperlinkButton>("Some Cases");
I'd expect to see some sort of Click() action, or Navigate() method that I could invoke on the "linkicareabout" variable, but I must be missing how it's done.
What you are looking for is the User object off the HyperlinkButton. All controls that WebAii comes with have that object. This way you can invoke any user action on any control type.
linkicareabout.User.Click()
The User object supports any user action you can think of and mimic real user interactions. Check out the documention here.
I was unable to do this myself and instead, had to write my own navigation code. For Firefox and IE, you can just use HtmlPage.Window.Navigate to navigate to the desired URL.
However, Safari and Chrome need some extra work. I had to use hidden HTML components and some javascript interops.
This workaround is detailed here.
Basically, it entails adding a hidden anchor and button to the HTML page containing your Silverlight control, and then modifying the anchor and clicking the button via calls to the DOM.
HtmlElement anchor = HtmlPage.Document.GetElementById("externalAnchor");
HtmlElement button = HtmlPage.Document.GetElementById("externalButton");
if ((anchor != null) && (button != null))
{
anchor.SetProperty("href", url);
button.Invoke("click", null);
}