About the author

Paul Maré is a Silverlight developer living in Sydney

Items of Interest

     
     
    Zero Gravity C#imp

    Using Code aCHORDingly

    clock August 9, 2010 12:45 by author ZeroGravityChimp

    Hello,

    Last week I showed you some basics to creating a Piano project in Silverlight.

    Repetitive Code

    The code at this point looks as above. In this case I would suggest making it slightly more reusable by employing a function such as shown below:

    Reusable Code

    You can go one step further. Since the rectangles are all named for the note that needs to play, you can create one event handler like below and send the name of the rectangle being clicked in order to play the right note.

    Reusable Code

    This is a great way to reduce 20+ lines of code to about 7 lines.

    It's time to add the other notes in the project. The grid structure that I would use would group the black keys separately so that they can float on top of the white keys. My grid has a width of 490, so I've created a bunch of columns for it as shown below, yielding black keys 40 pixels wide.

    Columns

    For each black key, Create a rectangle. To name it, I followed the naming of the audio files: C2 for C#/Db, D2 for D#/Eb and so forth. Each of these rectangles can be filled in black (or any other colour you like) and put into their correct columns.

    Reusable Code

    Please note that this is just one way in which to create a set of black rectangles or buttons. If you prefer to use a StackPanel, ButtonStack, or any other method you know of, go ahead! I have also added a DropShadow Effect to make them stand out a bit more. Follow the steps in my previous post to hook up the events, but this time you can use the reusable function such as:

    MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"

    As long as you name your MediaElements and Rectangles appropriately, such as "Media_C2" for Rectangle "C2", "Media_D2" for Rectangle "D2", etc. If any of this seems confusing to the readers, post a comment and I will clarify or give you the source code.

    Run the project and you will be able to click any of the notes and play some tunes! At this point, the piano still isnt fully functional, since you can't hit many notes at once.

    For my next trick, I will be adding some simple keyboard commands to the piano application. The first step to this would be to add an event handler for the keyboard. I will add the event to the "LayoutRoot" grid, so that any key press in the application will be detected.

    Reusable Code

    As you can see above, if you type these events into Visual Studio it will give you the option to automatically create the event handlers.

    I'm using a big switch statement for all the different keys as pictured below. You can use different keys for different notes, but I just went with the bottom row of the keyboard from Z to M and the keys just above them where the black notes are.

    Reusable Code

    Unfortunately we need to force the user to click the application so that key presses will be detected, so in a real application, I would suggest you make some kind of welcome screen to force the user to click. For now, click your first note before you start using the keys.

    Coming up, I'll figure out a way to auto-focus the application, and light up the notes that we're going to be playing for better visual effect. You will also notice that if you hold the keys down, the note will not sound clearly, so we have to implement some more in-depth sound-looping logic.

    Hope you could learn something from this post! If you can teach me something instead, feel free to post your comments below!

    Regards,

    Zero Gravity Chimp



    Some Side-Notes

    clock July 7, 2010 13:11 by author ZeroGravityChimp
    Hello readers,

    For a little bit of a change, I'm going to guide you through creating a simple application. The purpose of it is to play musical notes in response to clicks and keyboard commands. It is a digital piano.

    It's going to look like a piano. To achieve this, I've made it a fixed width application, and done the modifications to the UserControl below. If you need more detailed instructions on getting started see my earlier postings here.



    for the main notes (i.e. the larger white ones), we should create some columns. Create a grid inside the LayoutRoot in "Objects and Timeline" and add some columns. Start off by clicking them roughly along the top of the grid.



    we need 6 dividers to make 7 columns - one for each A, B, C, D, E, F, and G - the musical notes on a piano. Once these dividers are in place, you will see 7 "Star sized" icons above their respective columns. Click these icons to toggle until each is "Pixel sized".



    In the split view, or selecting each column by clicking beneath the icon, edit their width values and make them all equal.

    Create 7 Rectangles, by double clicking them on the toolbar on the left. This will add them with default settings. For each of these rectangles, reset the margins - since we will use the grids to determine the size of the rectangles, they can simply stretch.



    Name them starting from C to G, followed by A and B. That is how a piano octave is laid out. Now you need to change the Grid.Row property of each of these. The first should be 0, the next 1, and so forth up to 6. This can be edited in the "Layout" section of the properties of each Rectangle, or directly in the xaml.



    The next step is to add all of the audio files to the project. I have put the zip filled with the note sound bytes you will need here.

    I got these from an old open source Silverlight 1.0 Piano project which you can find here (also, the source, thanks to Chris Bowen's Blog). Credit to Microsoft for releasing this as part of their Silverlight 1 SDK back in the day. Our project won't replace, or be as good as, that one I just linked you to. Ours is just for learning and a bit of fun.

    Once you have downloaded them, add a new folder to the project called "Assets" and add the files to the folder using "Add existing item" from expression blend or Visual Studio as shown below.



    Rebuild the project now by pressing F5 to make sure it still runs without errors and the new files are recognised by the compiler.

    Now I'm going to introduce you to a feature of Silverlight called MediaElement. To find it, click the "More" icon along the bottom of the main toolbar and type in "media" in the search box. This will bring the control up into view. Note that other controls can also be found and browsed in this way.



    Go ahead and add 7 MediaElements to the page (you will need more eventually for all the sharp and flat notes in between) and name them the same as the notes but starting with Media_ like Media_C, Media_D, etc.

    These elements are designed to present some kind of media, in this case it is an audio file of wma format. It has functions like Play() and Stop() as well as a Position (like 00:00:01) which behaves like a track slider in common Media Players. We will use some of this functionality now.

    Select the MediaElement as you would any object in Objects and Timeline, and have a look at the Properties for that. You should be able to choose any of your wma files in the project as a "source". If you don't see them, you may need to rebuild or run the project.



    Choose the corresponding source for each element. You may also note that in the screenshot above i have grouped the keys with their media elements into a grid. This won't change much but it will make the project easier to read and understand. To group into grid, select some elements and press Ctrl+G.

    We want the Media to play based on what piano "Keys" are pressed. To do this, we need to act upon the click of each of the Rectangles we created earlier. Select the elements starting from C and click the "Events" tab as shown. Now all you need to do is double-click in the box next to "MouseLeftButtonDown" to add the event handler.



    You will then be automatically taken to the code file, and should see the following created for you:

    private void C_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
         // TODO: Add event handler implementation here.
    }

    The code we put in here will run when the rectangle is clicked. Change it as follows and run the project.

    private void C_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
         Media_C.Position = TimeSpan.FromMilliSeconds(0);
         Media_C.Play();
    }

    You will be able to hear a note play whenever you click on that rectangle.

    For the first round of this project I have implemented an event handler like that for each of the white squares, and played some notes using the mouse for fun. If you are following you would see that the piano doesn't really work very well yet, since you can't press multiple keys at once, and if you hold them in you get a terrible sound effect.

    In the next post I will add some keyboard events and change the code so that we have reusable functions instead of many separate event handlers. I'll also add the black (sharp and flat) notes into my project.

    Stay tuned!

    Zero Gravity Chimp


    Basics of Grid Layout: Creating Rows and Columns

    clock May 31, 2010 13:27 by author ZeroGravityChimp

    Hi again.


    The grid object in Silverlight is designed to allow a page that can dynamically resize to the client's window size. These days every browser is on a different resolution, from 800x600 up to 1600x1200 or more! People may expect your application to scale to their resolution.

    This can be achieved using grids and using their column and row features. This posting should explain step by step how to create and use columns and rows of a grid.

    Follow my previous posting http://www.zerogravitychimp.com/post/Basics-of-Grid-Layout-Setting-the-Design-size.aspx to get the application screenshotted below:

    As stated previously, your application will have a grid at its root level. Select this grid in the "Objects and Timeline" panel. You will see a light blue area on the top and left sides of the grid, floating a little away from the edge. If you hover your mouse pointer over these areas, you will see an orange row or column indicator.



    as shown above, create a column roughly where you want your divide to occur by simply clicking. This has automatically created 2 "ColumnDefinitions" for you. If you change to split view you will be able to view them in the XAML.



    A great trick I want to share with you is that if you want to change any details of the ColumnDefinition or RowDefinition in the design view. Move your mouse pointer between the 'lock' (or other) icon until your cursor changes to a white pointer with a little table icon next to it. If you click now it will select the column, and it will look as follows:



    When you have done so you can easily edit or view the Type and value (Width or Height) of a Column or Row Definition using the Properties area as shown. Please note that using design view you cannot edit the following properties, which are editable in the XAML directly:
    (B) MinWidth, MaxWidth for columns
    (B) MinHeight, MaxHeight for Rows.

    Build and Run the project now by pressing F5 from Expression Blend - see how this compares to the version before columns were added:



    Now this may seem like a small difference, but noticing the change is really important! The Rectangles on the left and the big blue one on the right are now sizing *Proportionately* to the total width. The proportion is based on the value you can see in the previous screenshot.

    To edit the way your columns are spaced, you can click and drag the small blue triangle at the top of your ColumnDefinition in the design view. Go into the split view and have a look at how the values change in the XAML when you resize the columns:



    In the screenshot above, I selected the column using the trick I described earlier in this post, and I can see that the values also change in the properties panel for that ColumnDefinition.

    Please note that all of these operations are also possible for the RowDefinition type, they work in the same fashion, and are created by clicking down the left of the grid.

    So far I haven't addressed the different types of columns and rows. These can be changed by clicking on the "Padlock" (or other) icon. Here's a quick run down of the types: Star, Pixel, and Auto:

    a) Star, which allows for Proportionate size, is the default. The values of each Star column or row are a fraction in the double format. Each of these together usually add up to 1, which represents the total size of the grid when it is rendered.

    b) Pixel sizes are literal, such as 300 pixels, and they will not stretch or resize based on the screen size or contents size.

    c) Auto sizes will try to shrink to the minimum size based on the contents, and grow if the contents of that column or row also grow.

    It can be very hard to understand when and how to use the different column and row types, and how to use them all in conjunction to get your desired effect. I will be going into this in detail in my upcoming posts.

    Feel free to provide me with your questions and I will answer them as best I can. Any other input is very welcome in the comments section below.

    Stay Tuned!

    Zero Gravity Chimp