0

Asp.Net MVC 2 Areas

Posted by Chris Brandsma on Mar 13, 2010 in Dotnet, Silver Light  | View Original Article
 

imageI’m looking into the new stuff in Asp.Net MVC 2, trying to figure out what is cool and what is just there.  Areas look like a nice addition.  Areas allow you to separate your Asp.Net MVC application into more distinct partitions.  So all of the Controllers, Models, Views, and even routes belong to one directory structure.  It is like having a sub-project inside of you MVC project.

Here is the problem, as I see it:  as an MVC project gets large, keeping all of the necessary pieces and parts for a set of controller actions straight can get a bit daunting.  I’ve ended up with duplicate folder structures in views and models, which can make navigation a pain.

To make a new Area, simply right-click anywhere in you MVC project, Add->Area.  As I said, you can do this from anywhere in the project structure, but the Areas are created in a new “Areas” folder.  When you name the Area, a new folder is created with the Areas name as well.

Once created you should see all the familiar Controllers, Models, and Views folders (all blank).  In addition to that, you will see an <name>AreaRegistration.cs file.  This inherits from AreaRegistration, and this is where any new Routes go.  In the file is a prebuilt route that should look similar to this:

   1: context.MapRoute(

   2:     "test1_default",

   3:     "test1/{controller}/{action}/{id}",

   4:     new { action = "Index", id = UrlParameter.Optional }

   5: );

So a url to the area would include /test1/ (name of my Area) in the path.  That would be good if you had multiple controllers with the same name, but if you don’t, just take out the “test1” and you won’t need it in the path.

Also, if you leave Area name in the route, you will have a little more work to, here is what one of mine looked like:  <%=Html.ActionLink("test", "Index", "test1/TestArea") %>.  But it turns out this is more correct:

<%=Html.ActionLink("test", "Index", "TestArea", new { area="Test1"}, new {}) %>

This also mean that any controller actions you want to link to outside if Area needs to include a blank area in the link, like this:

<%=Html.ActionLink("Home", "Index", "Home", new { area=""}, new {}) %>

In case you are wondering, the first object in the area is for route values, the second is for html attributes.

So the downside of using Areas is that you could complicate your routing in a hurry.  Plus it does not look like the Html helpers are there to lend you a hand either.  It is very doable, just annoying.  Of course, the easy fix is to remove the Area name from the route and move on.  That should be ok so long as you do not have two controllers with the same name.

So are Areas a compelling feature? I think so.  Plus, the larger the site, the more compelling Areas can become.  For smaller sites, probably not.  But I would not say no either.

Tags: , ,

 
0

MvcFutures

Posted by Tony Rasa on Mar 13, 2010 in Dotnet, Silver Light  | View Original Article
 

ASP.NET MVC 2 has been released (yay).  One of the pieces I like about it is in the MvcFutures assembly.  MvcFutures is where the MVC team puts code for features that may or may not make it into a future version of the MVC framework – undocumented, somewhat risky, but hey you get all the source code if you find yourself painted into a corner.

One of the long-standing MVC practices has been ‘Shun Magic Strings.’  For example, rather than specifying Controller/Action names in an ActionLink by string, we’ve always used an Expression<Action<TController>> instead to define the Controller class and Action method “in code.”  If the action changes in the future, this gives you somewhat better abilities to discover the problem sooner vs. later. 

MvcFutures includes a version of this idea, taken to the next level:  you provide the expression with the arguments you want passed to the action included – you don’t provide a 2nd anonymous type defining the arguments.  This gets rid of the somewhat confusing “null” arguments inside the expression, and just looks better overall.  Plus, if the arguments to the action change, you’ll get better warning of that as well.

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">    <h2>Magic Strings are Evil</h2>    <p>        <%= Html.ActionLink<HomeController>(c => c.FavoriteNumber(16), "A Number") %>        <%= Html.ActionLink<HomeController>(c => c.FavoriteNumber(32), "Another Number") %>        <%= Html.ActionLink<HomeController>(c => c.FavoriteNumber(42), "Yet Another Number") %>            </p></asp:Content>

I like this method MUCH better. 

The implementation that makes this happen is in Microsoft.Web.Mvc.Internal.ExpressionHelper.  Which even though it’s in an “Internal” namespace, is neither marked Internal, Sealed, or otherwise made unavailable (hallelujah).  So you can use this trick for all sorts of things.

There is also a System.Web.Mvc.ExpressionHelper in the official MVC assembly, which is used to implement the smart Html.TextBoxFor(m => m.Property) functionality.  This class is also NOT internal, not sealed, not obfuscated and hidden away.  We’ve used it to extend the Html.[control]For() abilities to some other control types.  Very useful stuff.  Plus its just interesting code to read.

One potentially big caveat:  I’m told that the Html.ActionLink<TController>() methods don’t work if you’re using Areas in your MVC application.  I haven’t tried this myself, we aren’t using Areas in any of our MVC 2 applications yet.  That might be why this functionality is hidden in MvcFutures and not out with the rest of the smart expression code.

Tags: , , , ,

 
0

March 22-25th 2010 ESRI Developer Summit

Posted by Al on Mar 12, 2010 in Dotnet, Silver Light  | View Original Article
 


In 2 weeks the ESRI Developer Summit will start in Palm Springs, if you haven’t register, there is still time.

clip_image001

 

Created for Developers
by Developers

Prepare for tomorrow's challenges at the ESRI Developer Summit (DevSummit). It's the place to be for developers interested in using spatial technology in their applications.

Bring your toughest questions for the ESRI engineers and hear insightful user presentations given by your peers. Register today

Hope I’ll see you there.

Cheers

Al

Tags: , ,

 
0

Silverlight 4: Implicit Themes and a Sneak Peek

Posted by Brian Lagunas on Mar 12, 2010 in Dotnet, Silver Light  | View Original Article
 

One of my major gripes with Silverlight 3 is the inability to theme your application.  Currently if you want to style a button for your application you will have to define a style similar to this:

<UserControl.Resources>
    <Style x:Key="myButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="Blue" />
        <Setter Property="Foreground" Value="Green" />
        <Setter Property="FontSize" Value="24" />
    </Style>
</UserControl.Resources>

Then, you have to set the Style property on the Button control you want to apply the style to:

<Button Content="Button 1" Style="{StaticResource myButtonStyle}" />

Now, what if I want to apply that same style to every button in my application?  Well I would have to go and find every single button in my application and set the Style property accordingly.

<Button Content="Button 1" Style="{StaticResource myButtonStyle}" />
<Button Content="Button 2" Style="{StaticResource myButtonStyle}" />
<Button Content="Button 3" Style="{StaticResource myButtonStyle}" />

How many buttons are in your application?  What a pain in the you know what.  Well not anymore.  New in Silverlight 4 will be the ability to set your styles implicitly.  What does this mean?  It means that you can now declare your style, give it a TargetType, and exclude the x:Key; then it will apply that style to any instance of the TargetType control type.

<UserControl.Resources>
    <Style TargetType="Button">
        <Setter Property="Background" Value="Blue" />
        <Setter Property="Foreground" Value="Green" />
        <Setter Property="FontSize" Value="24" />
    </Style>
</UserControl.Resources>
 
<Grid x:Name="LayoutRoot">
    <StackPanel>
        <Button Content="Button 1" />
        <Button Content="Button 2" />
        <Button Content="Button 3" />
    </StackPanel>
</Grid>

Notice that I don’t need to set the Style property on my button controls individually anymore.

implicit theming

Well what if I have a style that I want to implicitly use, but I have this one special button that I want to give a different style?  Well in that case, just create a new Style and give it a x:Key, then set the Style property on your control.

<Style x:Key="myOtherButtonStyle" TargetType="Button">
   <Setter Property="Background" Value="Orange" />
   <Setter Property="Foreground" Value="Red" />
   <Setter Property="FontSize" Value="12" />
</Style>
 
<Button Content="Button 1" />
<Button Content="Button 2" Style="{StaticResource myOtherButtonStyle}" />
<Button Content="Button 3" />

special style

Now, your special button will use your new style, and all others will remain themed.

Sneak Peek: Silverlight Application Themes

Tim Heuer has recently given us a preview of three new theme packs coming to Silverlight.

“GrayScale”

GrayScale Theme

“Windows Theme”

Windows Theme

“Metro”

Metro Theme

Thanks Tim!

Tags: , , ,

 
0

No Preview Images in File Open Dialogs on Windows 7

Posted by Rick Strahl on Mar 10, 2010 in Dotnet, Silver Light  | View Original Article
 

I’ve been updating some file uploader code in my photoalbum today and while I was working with the uploader I noticed that the File Open dialog using Silverlight that handles the file selections didn’t allow me to ever see an image preview for image files. It sure would be nice if I could preview the images I’m about to upload before selecting them from a list. Here’s what my list looked like:

FileOPenDialog

This is the Medium Icon view, but regardless of the views available including Content view only icons are showing up.

Silverlight uses the standard Windows File Open Dialog so it uses all the same settings that apply to Explorer when displaying content. It turns out that the Customization options in particular are the problem here. Specifically the Always show icons, never thumbnails option:

FolderOptions

I had this option checked initially, because it’s one of the defenses against runaway random Explorer views that never stay set at my preferences. Alas, while this setting affects Explorer views apparently it also affects all dialog based views in the same way. Unchecking the option above brings back full thumbnailing for all content and icon views. Here’s the same Medium Icon view after turning the option off:

FileOpenDialogPics

which obviously works a whole lot better for selection of images.

The bummer of this is that it’s not controllable at the dialog level – at least not in Silverlight. Dialogs obviously have different requirements than what you see in Explorer so the global configuration is a bit extreme especially when there are no overrides on the dialog interface. Certainly for Silverlight the ability to have previews is a key feature for many applications since it will be dealing with lots of media content most likely.

Hope this helps somebody out. Thanks to Tim Heuer who helped me track this down on Twitter.

© Rick Strahl, West Wind Technologies, 2005-2010
Posted in Silverlight  Windows  
kick it on DotNetKicks.com

Tags: , , ,

 
0

Displaying Multimedia Content In A Floating Window Using FancyBox

Posted by 4GuysFromRolla.com Headlines on Mar 9, 2010 in Dotnet, Silver Light  | View Original Article
 

While surfing the web you may have come across websites with images and other multimedia content that, when clicked, were displayed in a floating window that hovered above the web page. Perhaps it was a page that showed a series of thumbnail images of products for sale, where clicking on a thumbnail displayed the full sized image in a floating window, dimming out the web page behind it. Have you ever wondered how this was accomplished or whether you could add such functionality to your ASP.NET website?

In years past, adding such rich client-side functionality to a website required a solid understanding of JavaScript and the "eccentricities" of various web browsers. Today, thanks to powerful JavaScript libraries like jQuery, along with an active developer community creating plugins and tools that integrate with jQuery, it's possible to add snazzy client-side behaviors without being a JavaScript whiz.

This article shows how to display text, images, and other multimedia content in a floating window using FancyBox, a free client-side library. You'll learn how it works, see what steps to take to get started using it, and explore a number of FancyBox demos. There's also a demo available for download that shows using FancyBox to display both text and images in a floating window in an ASP.NET website. Read on to learn more!
Read More >

Tags: ,

 
0

Silverlight DataGrid – Populate Dynamic Columns from a Child Collection

Posted by Brian Lagunas on Mar 8, 2010 in Dotnet, Silver Light  | View Original Article
 

Lets face it, any one building LOB (line of business) applications know that their users love Microsoft Excel.  If the users had their way, they would do everything in Excel.  Due to this known fact, when building Silverlight LOB applications, there is often a need to flatten out an object for editing in a grid.  For example; you may have an object that has an n-level number of properties or attributes that aren’t known until runtime, but you want to edit the object in a single row in a grid. You don’t want to add a bunch of properties on your object like Prop1, Prop2, Prop3, etc.., just so you can bind it to your grid.  You want to dynamically add columns to your grid and bind those columns to the correct object in the child collection at run time.

Well, this is much easier than you may think and I will show you how to accomplish this with just a few simple helper methods, and you can use any grid of your choice.  For this example, I will be using the DataGrid that comes with the Silverlight Toolkit. Make sure you download and install it, because I am not including the System.Windows.Controls.Data assembly required for the DataGrid.

It will be located at c:\Program Files\Microsoft SDKs\Silverlight\v3.0\Libraries\Client\System.Windows.Controls.Data.dll

In my scenario I am building a staffing application and I have a “StaffMember” object that has a collection of “Period” objects as a child property.  My objects look something like this:

public class StaffMember
{
    public string Name { get; set; }
    public string Department { get; set; }
    public ObservableCollection<Period> Periods { get; set; }
}
 
public class Period
{
    public string Title { get; set; }
    public int Hours { get; set; }
}

Pretty simple!  now, lets create our DataGrid that will show our data for editing.

<UserControl x:Class="SilverlightApplication1.MainPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:grid="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
    <Grid x:Name="LayoutRoot">
        <grid:DataGrid x:Name="dataGrid"/>
    </Grid>
</UserControl>

Okay, now I don’t know how many Periods my StaffMember will have until I get the data back from the database at run time.  For demonstration purposes, I just created a method on my StaffMember class that would create my objects by iterating through a loop.

public static List<StaffMember> GetData()
{
    List<StaffMember> dataList = new List<StaffMember>();
    for (int i = 0; i < 3; i++)
    {
        StaffMember member = new StaffMember { Name = String.Format("Name#{0}", i), Department = String.Format("Department#{0}", i) };
        ObservableCollection<Period> periods = new ObservableCollection<Period>();
        for (int j = 0; j < 5; j++)
            periods.Add(new Period() { Title = String.Format("Period#{0}-{1}", i, j), Hours = j });
        member.Periods = periods;
        dataList.Add(member);
    }
    return dataList;
}

Now, we need to set the datasource on the DataGrid.  Since we are creating the columns at runtime make sure you set AutoGenerateColumns to false;

List<StaffMember> dataList = StaffMember.GetData();
dataGrid.AutoGenerateColumns = false;
dataGrid.ItemsSource = dataList;
dataGrid.Columns.Clear();

Next, lets take care of creating the easy columns first.  I created a method that its’ sole purpose is to give me new DataGridTextColumns.

private static DataGridTextColumn CreateTextColumn(string fieldName, string title)
{
    DataGridTextColumn column = new DataGridTextColumn();
    column.Header = title;
    column.Binding = new System.Windows.Data.Binding(fieldName);
    return column;
}

Using this method we can create our first two columns.

dataGrid.Columns.Add(CreateTextColumn("Name", "Staff Name"));
dataGrid.Columns.Add(CreateTextColumn("Department", "Company Department"));

Your DataGrid should now look something like this.

text columns added to grid

Now we need to create our columns based off the Periods collection.  To do this we will utilize a DataGridTemplateColumn.  The first thing we need to do is create a method that will dynamically create a DataTemplate that the DataGridTemplateColumn will use as the CellTemplate.

private string CreateColumnTemplate(int index, string propertyName)
{
    StringBuilder CellTemp = new StringBuilder();
    CellTemp.Append("<DataTemplate ");
    CellTemp.Append("xmlns='http://schemas.microsoft.com/winfx/");
    CellTemp.Append("2006/xaml/presentation' ");
    CellTemp.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>");
    CellTemp.Append(String.Format("<TextBlock Text='{{Binding Periods[{0}].{1}}}'/>", index, propertyName));
    CellTemp.Append("</DataTemplate>");
    return CellTemp.ToString();
}

What I am doing here is using a StringBuilder to create a DataTemplate, represented by XAML.  Pay special attention to the TextBlock’s binding.  I am using String.Format to create my binding string base off the index the of the object in the collection and the name of the property on the child object I want to bind to.  Now, lets create our template that will be used for editing.

private string CreateColumnEditTemplate(int index, string propertyName)
{
    StringBuilder CellTemp = new StringBuilder();
    CellTemp.Append("<DataTemplate ");
    CellTemp.Append("xmlns='http://schemas.microsoft.com/winfx/");
    CellTemp.Append("2006/xaml/presentation' ");
    CellTemp.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>");
    CellTemp.Append(String.Format("<TextBox Text='{{Binding Periods[{0}].{1}, Mode=TwoWay}}'/>", index, propertyName));
    CellTemp.Append("</DataTemplate>");
    return CellTemp.ToString();
}

This method is very similar to the previous one we wrote, but notice the subtle difference; I am using a TextBox instead of a TextBlock, and the Mode is set to TwoWay.  This will allow us to edit the values in the DataGrid.  Now we need a method that will actually create the TemplateColumns.

private DataGridTemplateColumn CreateTemplateColumn(int i, string propName)
{
    DataGridTemplateColumn column = new DataGridTemplateColumn();
    column.Header = String.Format("Period#{0}.{1}", i, propName);
    column.CellTemplate = (DataTemplate)XamlReader.Load(CreateColumnTemplate(i, propName)); //display template
    column.CellEditingTemplate = (DataTemplate)XamlReader.Load(CreateColumnEditTemplate(i, propName)); //edit template
    return column;
}

Notice that we are setting the CellTemplate and CellEditTemplate by using the XamlReader to load our StringBuilder result and cast it as a legitimate DataTemplate the column can use.  Now that we have the method that will create our TemplateColumns, lets go ahead and build our dynamic columns to the n-level.  We do this by looping though the number of columns that need to be created and using our CreateTemplateColumn method to add the new columns to the DataGrid.

int periodCount = dataList[0].Periods.Count;
for (int i = 0; i < periodCount; i++)
{
   dataGrid.Columns.Add(CreateTemplateColumn(i, "Hours"));
}

Now of course, in the real world you would not want to use the first index of the child collection to figure out how many columns to build.  I would recommend some kind of definition object that will define what columns and how many columns to build.

completed DataGrid 

That is it.  You have now successfully satisfied your customer’s addiction to Excel.  Well, at least a little bit.

Download Source

Tags: , , ,

 
0

Comparing LINQ to SQL vs the classic SqlCommand

Posted by Al on Mar 7, 2010 in Dotnet, Silver Light  | View Original Article
 


When you are coming from using SqlCommand and SqlConnection is difficult to move to another library for your database needs. For those people still in the limbo to make the decision to move to another DAL, here is a comparison to help you see the light or to move away for ever.

 

How to do a select query using SqlCommand:

   1: SqlConnection myConnection = new SqlConnection(@"Data Source=PROG-3407\SQLEXPRESS;Initial Catalog=Demo;Integrated Security=True;Pooling=False");
   2:  
   3:             string sQuery = "SELECT * FROM Table1";
   4:  
   5:             SqlCommand myCommand = new SqlCommand(sQuery);
   6:             myCommand.Connection = myConnection;
   7:  
   8:             myConnection.Open();
   9:  
  10:             SqlDataReader dataReader = myCommand.ExecuteReader();
  11:  
  12:             while (dataReader.Read() == true)
  13:             {                
  14:                 string sID = dataReader[0].ToString();
  15:                 string sName = dataReader[1].ToString();
  16:                 string sCity = dataReader[2].ToString();
  17:  
  18:                 MyData dat = new MyData()
  19:                 {
  20:                     ID = Int32.Parse(sID),
  21:                     Name = sName,
  22:                     City = sCity
  23:                 };
  24:                 myDataCollection.Add(dat);                
  25:             }
  26:  
  27:             GridView1.DataSource = myDataCollection;
  28:             GridView1.DataBind();
  29:  
  30:             dataReader.Close();
  31:             myConnection.Close();

And now a select query in LINQ to SQL

 

   1: Table1DataContext dataContext = new Table1DataContext();
   2:                        
   3:            var all = from p in dataContext.Table1s orderby p.City select p;
   4:            
   5:            GridView1.DataSource = all;
   6:            GridView1.DataBind();

Pretty short isn’t it?, the select statement is inline with a little help from intellisense.

 

Insert in SqlCommand

   1: using (SqlConnection myConnection = new SqlConnection(@"Data Source=PROG-3407\SQLEXPRESS;Initial Catalog=Demo;Integrated Security=True;Pooling=False"))
   2:             {                
   3:                 string sQuery = "INSERT INTO Table1 (Name,City) values(@Name,@City)";
   4:  
   5:                 SqlCommand myCommand = new SqlCommand(sQuery);
   6:                 myCommand.Connection = myConnection;
   7:  
   8:                 myConnection.Open();
   9:                                 
  10:                 myCommand.Parameters.AddWithValue("@Name", TextBoxName.Text);
  11:                 myCommand.Parameters.AddWithValue("@City", TextBoxCity.Text);
  12:  
  13:                 myCommand.ExecuteNonQuery();
  14:             }

 

Insert in LINQ in SQL

   1: Table1DataContext dataContext = new Table1DataContext();
   2:  
   3:             Table1 row = new Table1()
   4:             {
   5:                 City = TextBoxCity.Text,
   6:                 Name = TextBoxName.Text
   7:             };
   8:  
   9:             dataContext.Table1s.InsertOnSubmit(row);
  10:             dataContext.SubmitChanges();

 

Hope this helps

Cheers

Al

Tags: , ,

 
0

Text-To-Speech in Silverlight Using WCF

Posted by Brian Lagunas on Mar 7, 2010 in Dotnet, Silver Light  | View Original Article
 

Back in February, I wrote a blog post showing you how to, using Silverlight 4 OOB (out of browser) with elevated trust, access system devices; including how to use the SAPI.SpVoice API through the new Silverlight 4 COM Interop feature to implement text to speech. The biggest problem to that approach is that it will only work on the Windows platform.

So, I started thinking to myself, that the real purpose behind Text-To-Speech isn’t just the cool factor, but it is accessibility for impaired users.  I have been doing web development for nearly a decade, and I have always been conscious about web users with impairments that may make viewing or navigating my websites more difficult.  Text-To-Speech isn’t very helpful if it will only work in a fully trusted out of browser Silverlight 4 application on a Windows machine. So instead, lets create a Text-To-Speech solution that will work inside the browser, on any browser, on any machine.  And heck, I want this to be in Silverlight 3.

Lets get started by creating a new Silverlight 3 application, and be sure to include a web project as well.

create new silverlight project

Right click the web project and add a reference to the System.Speech.dll.

add reference to System.Speech

Next, lets right click the web project and click Properties –> Web and set the specific port number to your liking, I set mine to 1914. This will come in handy when we create our WCF service.

set port number

Now we need to create the WCF service that will take our text and send it back as a WAV stream, so go ahead and right click the web project and select “Add New Item”.  From this list add a new WCF service and name is SpeechService.  Now this is important; when you have created your WCF service an endpoint is created for you in the Web.config file.  You need to change the binding of the endpoint to basicHttpBinding.  Silverlight only works using basicHttpBinding, and will not create the ServiceReferences.ClientConfig file properly if you do not do this.

change endpoint binding  to basicHttpBinding

Now, lets add an OperationCOntract to your WCF services interface called Speak that returns a byte[], and takes a string parameter.

[ServiceContract]
public interface ISpeechService
{
    [OperationContract]
    byte[] Speak(string textToSay);
}

The implementation of this method will look like the following:

public byte[] Speak(string textToSay)
{
    SpeechSynthesizer ss = new SpeechSynthesizer();
    MemoryStream ms = new MemoryStream();
    ss.SetOutputToWaveStream(ms);
    ss.Speak(textToSay);
    return ms.ToArray();
}

The next thing we need to do is create our UI in Silverlight.  Here is what mine looks like.

<Grid x:Name="LayoutRoot">
<StackPanel>
    <TextBox x:Name="_txtTextToSay" />
    <Button Content="Speak To Me" Click="Button_Click" />
    <MediaElement x:Name="_audioPlayer"/>
</StackPanel>
</Grid>

Create an event handler for your button.  Next add a service reference to your SpeechService in your web project.

add service reference to your speechservice

The next part is somewhat complicated and time consuming.  You have to write your own WAVV decoding class that takes the byte array that is return from the service and converts it to a System.Windows.Media.MediaStreamSource. Luckily for you, I already did this for you with the help of some resources on MSDN.  In the button’s event handler add this code:

private void Button_Click(object sender, RoutedEventArgs e)
{
    SpeechServiceClient client = new SpeechServiceClient("BasicHttpBinding_ISpeechService");
    client.SpeakCompleted += (o, ea) =>
        {
            WavMediaStreamSource audioStream = new WavMediaStreamSource(new MemoryStream(ea.Result));
            _audioPlayer.SetSource(audioStream);
        };
    client.SpeakAsync(_txtTextToSay.Text);
}

Basically what this does is uses the WavMediaStreamSource class I created that inherits from MediaStreamSource, takes the byte[] returned from the SpeechService and converts it back to a stream, then is passes it off to my WAV decoding classes, which is used as the source for the MediaElement responsible for playing the audio.

All that is next is to build your solution and start making your Silverlight applications more accessible.

Download the Source

Tags: , , ,

 
0

Creating a Custom Silverlight Pre-Loader

Posted by Brian Lagunas on Mar 5, 2010 in Dotnet, Silver Light  | View Original Article
 

I have been doing Silverlight development since it was released. One question I get asked a lot is how do to create a custom pre-loader for my application. What do I mean by pre-loader? Well, it can be called many things; it could be called a pre-loader, splash screen, or a loading screen. No matter what you want to call it, here is the one you get by default.

default Silverlight pre-loader

I thought creating a custom pre-loader was common knowledge, but I guess I was wrong. So, what is a custom pre-loader really? Well, it is a small and lightweight Silverlight application that runs while your main Silverlight application is being downloaded to the client. Creating your own is really easy and only involves a few basic steps.

The first thing we need to do is add a Silverlight JavaScript  page to the Web project of your Silverlight application. So just right click your Web project and click add new item, then select Silverlight JScript Page.

add new silverlight jscript page

You can name it whatever you want. I named my SplashScreen.xaml. When you click “Add” you will notice two files were created for you; a XAML file and a JavaScript file.

image

The XAML file is where you will create your pre-loader UI. So lets create a simple UI.

<Canvas        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        x:Name="parentCanvas"        Width="850"        Height="600"        Background="OldLace"        >  <Canvas Canvas.Top="228.834" Canvas.Left="246.329" Width="357" Height="31.379">    <Rectangle Width="27.545" Height="1" x:Name="uxProgress" Canvas.Top="29.545" Canvas.Left="1.4">      <Rectangle.RenderTransform>        <TransformGroup>          <ScaleTransform x:Name="uxProgressBar" ScaleX="1" ScaleY="0"/>          <SkewTransform AngleX="0" AngleY="0"/>          <RotateTransform Angle="270"/>          <TranslateTransform X="0" Y="0"/>        </TransformGroup>      </Rectangle.RenderTransform>      <Rectangle.Fill>        <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">          <GradientStop Color="#FFFFFFFF" Offset="1"/>          <GradientStop Color="#FFFFFFFF" Offset="0"/>          <GradientStop Color="#FF2975D0" Offset="0.28"/>          <GradientStop Color="#FF2975D0" Offset="0.72"/>        </LinearGradientBrush>      </Rectangle.Fill>    </Rectangle>

    <TextBlock x:Name="uxStatus" Height="25" Canvas.Left="125" Text="Loading..." TextWrapping="Wrap" Canvas.Top="4.16"/>

    <Path Width="356.85" Height="1" Fill="#FF3A3A3A" Stretch="Fill" Stroke="#FF000000" Canvas.Top="0" Data="M0,170.5 L356.84209,170.5" Opacity="0.35"/>    <Path Width="1.662" Height="29.03" Fill="#FF3A3A3A" Stretch="Fill" Stroke="#FF000000" Canvas.Top="0.48" Canvas.Left="0.2" Data="M360,168 L360,0" Opacity="0.35" />

    <Path Width="357.84" Height="1" Fill="#FF3A3A3A" Stretch="Fill" Stroke="#FF000000" Canvas.Top="29" Data="M0,170.5 L356.84209,170.5" Opacity="0.35"/>    <Path Width="358.85" Height="1" Fill="#FFA2A2A2" Stretch="Fill" Stroke="#FF000000" Canvas.Top="30" Data="M0,170.5 L356.84209,170.5" Opacity="0.25"/>    <Path Width="1.662" Height="30" Fill="#FF3A3A3A" Stretch="Fill" Stroke="#FF000000" Canvas.Left="356.01" Data="M360,168 L360,0" Opacity="0.35" Canvas.Top="-0.498"/>    <Path Width="1" Height="31" Fill="#FFA2A2A2" Stretch="Fill" Stroke="#FF000000" Canvas.Left="357.333" Data="M360,168 L360,0" Opacity="0.245" Canvas.Top="-0.498" />  </Canvas></Canvas>

I actually copied this XAML from MSDN because I was to lazy to write my own.

The JavaScript file is where you will interact with you pre-loader.  To do this there are three properties that are exposed by the Silverlight plug-in:

  1. splashscreensource: The URI of a XAML page that displays while the primary package (source) is being downloaded.
  2. onsourcedownloadprogresschanged: References a JavaScript event handler that will be invoked continuously while the source is being downloaded.
  3. onsourcedownloadcomplete: References a JavaScript event handler that will be invoked once, when the source download is complete.

Enter Params:

You will need to add two Object Params to your page hosting the Silverlight application.

<param name="splashscreensource" value="SplashScreen.xaml"/><param name="onSourceDownloadProgressChanged" value="onSourceDownloadProgressChanged" />

The first one tells the host where to find the custom XAML file you created. The second one tells it which JavaScript function to execute when the sourceDownloadProgressChanged event fires.

So go ahead and open up your JavaScript file and delete all the code that is in there and replace it with this:

function onSourceDownloadProgressChanged(sender, eventArgs) {    sender.findName("uxStatus").Text = "Loading: " + Math.round((eventArgs.progress * 1000)) / 10 + "%";    sender.findName("uxProgressBar").ScaleY = eventArgs.progress * 356;}

The next step is very important. Make sure you add your JavaScript file into the head tag of your hosting page.

<script type="text/javascript" src="splashscreen.js"></script>

Now in order to test this thing, you need to add something very big to your main Silverlight application, set its Build Action to Content, and set Copy to Output Directory to Copy if newer.  I added a video file that was about 100MB in size. Now run your application.

custom pre-loader

And there is our custom pre-loader.

For more information on creating custom pre-loaders visit http://msdn.microsoft.com/en-us/library/cc838130(VS.95).aspx

Download the Source

Tags: , , ,

Copyright © 2010 Answer My Query All rights reserved. Maintained by Orange Brains .