How do I set the Startup page in Silverlight?
Not sure if am googling for the wrong terminology or it just does not seem to be mentioned anywhere.
Cheers
The term "Startup page" is somewhat ambiguous. Inside a Silverlight application you probably mean one of a few things.
The initial UserControl to load as the RootVisual
In app.xaml.cs you will find code like :-
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new MainPage();
}
Where MainPage is the user control that is the initial root visual. You can change this is your own choice.
Perhaps though you want to set the RootVisual to one of a number of possible choices. In which case you would need to use InitParams. Something like:-
private void Application_Startup(object sender, StartupEventArgs e)
{
Type t = Type.GetType("SilverlightApplication1." + e.InitParams["StartupPage"]);
this.RootVisual = Activator.CreateInstance(t);
}
You then need to include the InitParams value in the <object> tag in the host HTML:-
<object ...>
...
<param name="InitParams" value="StartupPage=Page1" />
</object
Use the navigation framework
Another approach would be needed if you building a navigation application. In this case the MainPage will contain a Frame with a Source proeperty that would contain the initial URL to map.
With this type application you could specify alternative pages to load by simply adding a path following the # in the url of the page.
Related
I have a Silverlight application which has a RadHtmlPlaceholder which points to ssrs to display reports like so:
<telerik:RadHtmlPlaceholder SourceUrl="http://serverName/ReportServer/Pages/ReportViewer.aspx?/Northwind/Employees&rs:Command=render" />
This works fine but when I have a report that allows you to drill down to display a child report, there is no way of getting back to the parent report without having to load the whole lot again. There doesn't seem to be an option to turn on the navigate back button toolbar option and I've seen other ways of implementing a back button by using javascript to set the window location back one in the history, but obviously this won't work in a Silverlight application. Is there anyway to implement a navigate back button?
Take a look at this thread over in the Telerik forums: http://www.telerik.com/community/forums/silverlight/htmlplaceholder/html-place-holder-back-forward-refresh.aspx
Basically you need to get a handle on the IFrame from the presenter and inject some JavaScript. The history object also has a length property you can use to evaluate if your buttons should be enabled.
public MainPage()
{
InitializeComponent();
// Get the IFrame from the HtmlPresenter
HtmlElement iframe = (HtmlElement)htmlPlaceholder.HtmlPresenter.Children[0];
// Set an ID to the IFrame so that can be used later when calling the javascript
iframe.SetAttribute("id", "myIFrame");
}
private void Refresh_Click(object sender, RoutedEventArgs e)
{
// Code to be executed
string code = "document.getElementById('myIFrame').contentWindow.location.reload(true);";
HtmlPage.Window.Eval(code);
}
private void Back_Click(object sender, RoutedEventArgs e)
{
// Code to be executed
string code = "document.getElementById('myIFrame').contentWindow.history.back();";
HtmlPage.Window.Eval(code);
}
private void Forward_Click(object sender, RoutedEventArgs e)
{
// Code to be executed
string code = "document.getElementById('myIFrame').contentWindow.history.forward();";
HtmlPage.Window.Eval(code);
}
}
I Have attached a silver light user control (ex: FirstUserControl.xaml) into my silverlight navigation page project. If I wanna run the application, i need to show the added user control as startup page. How can I set the user control as defualt page in silverlight?
Can any one please give me the solution for this?
You can set it in your App.cs Application_Startup method:
private void Application_Startup(object sender, StartupEventArgs e)
{
// Specify the main application UI
this.RootVisual = new FirstUserControl();
}
I have a silverlight project which contains 2 silverlight controls Control_1 and Control_2. Please note that its in same app.Now I have asp.net project which will use any of these silverlight control (either Control_1 or Control_2).
Challenge is how do I tell silverlight which control to load. I used param property in html object to pass the parameters and tell the app which control to load at runtime?
But what if there are more than 2 controls in same project? We cannot have a long switch case statement in the app file only to load the controls. Is there any better way?
No, There isn't, and this is not about Silverlight itself, this is normal logic.
In your App.xaml file, put this:
using System.Windows; // Application, StartupEventArgs
namespace SilverlightApplication
{
public partial class App : Application
{
public App()
{
InitializeComponent();
}
private void Application_Startup(object sender, StartupEventArgs e)
{
// Specify the main application UI
if(SomeCondition == true)
this.RootVisual = new Control1();
else
this.RootVisual = new Control2();
// In the same way, you may define a switch statment
}
}
}
You may decide what that condition is by passing parameters to the XAP file, and finally you access those by accessing e.InitParams in Application_Startup
For more info: Application.RootVisual
I want some suggestions to implement this functionality with a neat design and without any code replication. I have an application with many views and grid control in most of the views. I need to add an export functionality (export records to excel).The grid control supports this OOB, just need to call 'Grid.Export()'. I am planning a UI button on the side of every grid and call this method.
So, obviously I need to write the code in code-behind only since I need the control's instance to invoke the method. But, I like to keep the code in one place and somehow invoke the code from all Xamls. (all WPF views).
One technique is to write a BaseView class and derive all Views from this.
But would like to know if WPF suppots any techniques by which I can achieve this. (behaviours etc..?)
Thanks,
Mani
Create a UserControl that includes both the datagrid and the export button. In effect, make it part of the grid itself.
Use this UserControl instead of the default datagrid in all of your views, and you're done.
Furthermore, if you ever have to modify the look and feel of your button or its behaviour, you have only one place in which to change it, and it will be updated in all of your views.
One of solutions is to use WPF routed command.
Note: I wrote this answer with the assumption that your "View" is a subclass of Window class.
First, add a custom routed command to your project.
public static class MyCommands
{
private static readonly RoutedUICommand exportCommand = new RoutedUICommand("description", "Export", typeof(MyCommands));
public static RoutedUICommand ExportCommand
{
get
{
return exportCommand;
}
}
}
In each View, set your custom command to Button.Command and bind a target object to Button.CommandTarget.
<Button Command="local:MyCommands.ExportCommand" CommandTarget="{Binding ElementName=dataGrid1}">Export</Button>
Firnally, in your Application class (named App by default), register a command binding between your custom command and Window.
public partial class App : Application
{
public App()
{
var binding = new CommandBinding(MyCommands.ExportCommand, Export, CanExport);
CommandManager.RegisterClassCommandBinding(typeof(Window), binding);
}
private void Export(object sender, ExecutedRoutedEventArgs e)
{
// e.Source refers to the object is bound to Button.CommandTarget.
var dataGrid = (DataGrid)e.Source;
// Export data.
}
private void CanExport(object sender, CanExecuteRoutedEventArgs e)
{
// Assign true to e.CanExecute if your application can export data.
e.CanExecute = true;
}
}
Now, App.Export is invoked when user click a button.
Sample is available here.
I'm in the process of removing the XAML from my Silverlight project and making it use only code (as per this article).
Here is my very simple startup event for a Silverlight application (with the standard App.xaml from the template project):
private void Application_Startup(object sender, StartupEventArgs e)
{
Grid grid = new MainPage();
this.RootVisual = grid;
var mediaElement = new MediaElement();
mediaElement.MediaFailed += (s, ea) => { mediaFailed = true; };
mediaElement.Source = new Uri(#"/Content/Some Music.mp3", UriKind.Relative);
grid.Children.Add(mediaElement);
}
Where the MP3 file is set to "Build Action: None, Copy if newer" (ie: it's beside the XAP). Here's the XAML for MainPage:
<Grid x:Class="TestGame.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Grid>
And the C# - nothing unusual here at all.
public partial class MainPage : Grid
{
public MainPage()
{
InitializeComponent();
}
}
That all works so far. So my question is this: why is it that when I change
Grid grid = new MainPage();
to
Grid grid = new Grid();
the mediaElement.MediaFailed event gets called (with a AG_E_NETWORK_ERROR)?
The only interesting thing that InitializeComponent is doing is calling Application.LoadComponent (it's the default generated code). So what might that function be doing that allows source URIs to work?
It seems that Application.GetResourceStream still works just fine. But I need to be able to get a few resources external to the XAP.
(Note: it seems this guy is having the same problem - but no one answered his question.)
The key factor is UriKind.Relative. The question is to what is it relative?
One of the effects of LoadComponent is that it shifts the location of "/". Before LoadComponent executes the path "/" refers to the same location as it would do in the host browser. After LoadComponent "/" refers to a hybrid of the root contents of the Xap and the folder that contains the Xap.
Since you are running this via a standalone test html page "/" in your second example refers to the root of the physical drive, e.g. "c:\".
If you change the Url to "Content/Some Music.mp3" (that is remove the "/" prefix) and assuming your test html page is the same folder as the Xap it should work as expected.
Note you can't escape the hybrid path with the parent path "..", Silverlight doesn't let you do that.