If you are interested in HTML5: here is a few links to visit :
And here is a presentation of HTML5 made in 2009 by Brad Neuberg (Google) :
Introduction to HTML 5 from Brad Neuberg on Vimeo.
If you are interested in HTML5: here is a few links to visit :
And here is a presentation of HTML5 made in 2009 by Brad Neuberg (Google) :
Introduction to HTML 5 from Brad Neuberg on Vimeo.
Yesterday was a web tool’s day : Microsoft released 7 free products for the web developpers.
Here is the Scott Guthrie’s post about it : http://weblogs.asp.net/scottgu/archive/2011/01/13/announcing-release-of-asp-net-mvc-3-iis-express-sql-ce-4-web-farm-framework-orchard-webmatrix.aspx
You can install most of these products from the Microsoft Web Platform Installer
I already installed webmatrix :
There is no “built in†numeric textbox in the current Silverlight for Windows phone.
Here a few solutions to realize one anyway : it remembers me the early years of the .NET framework or nothing was in the framework …
All my solutions are based on the same principle : we handle the keydown event of a textbox then we check the code of the pressed key.
If the code matches a number, we let it do, in the other case we stop the process.
In the xaml of the application, we add a textbox and we set it’s InputScrope property to “TelephoneNumber†to set the keyboard to a layout with numbers (we should also use the “Number†value for this property but the keys are smaller, this is not the best for a small device) so the input keyboard will look like this
This is not enough, because we can use the special characters (*, #, ., / and the space bar).
So we add an handler for the keydown event
<TextBox Name="SimpleTbx" InputScope="TelephoneNumber" KeyDown="SimpleTbx_KeyDown"/>
In the code behind, we will add our logic:
First, we specify an array of the allowed key codes :
private readonly Key[] numeric = new Key[] {Key.Back, Key.NumPad0, Key.NumPad1, Key.NumPad2, Key.NumPad3, Key.NumPad4, Key.NumPad5, Key.NumPad6, Key.NumPad7, Key.NumPad8, Key.NumPad9 };
(don’t forget the back button because we still want to use it ! It works also if I don’t put it in the array but I prefer to let it just in case)
In the keydown event handler we check the pressed key code:
private void SimpleTbx_KeyDown(object sender, KeyEventArgs e) { // handles non numeric if (Array.IndexOf(numeric, e.Key) == -1) { e.Handled = true; } }
If the array don’t contains the code we stop to process the key.
That’s it for the first solution.
If we don’t want to repeat the operations of the first solution on every textbox in the project we can use a user control.
So we add an user control to the project (right click on the project-> Add –> new item)
In this user control we add a textbox and we repeat exactly the same operations than for the first solution.
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}" Height="Auto" Width="Auto"> <TextBox Name="NumericTextBox" KeyDown="NumericTextBox_KeyDown" InputScope="TelephoneNumber"/> </Grid>
We still have a little additional work to do : add a property linked to the text of the textbox. So we can retrieve the result in our page.
public string Text { get { return NumericTextBox.Text; } set { NumericTextBox.Text = value; } }
To use it in the mainpage, we need to reference the namespace of the usercontrol:
xmlns:my="clr-namespace:WPNumericTextBox.Controls"
then we can use it this way :
<my:NumericTextBoxUserControl x:Name="NumericTbxUC" />
End of the second solution.
We can inherit the textbox and made it responsive to numbers only:
Here is the complete code :
using System; using System.Windows.Controls; using System.Windows.Input; namespace WPNumericTextBox.Controls { public class NumericTextBox : TextBox { private readonly Key[] numeric = new Key[] {Key.Back, Key.NumPad0, Key.NumPad1, Key.NumPad2, Key.NumPad3, Key.NumPad4, Key.NumPad5, Key.NumPad6, Key.NumPad7, Key.NumPad8, Key.NumPad9 }; public NumericTextBox() { this.InputScope = new InputScope(); this.InputScope.Names.Add(new InputScopeName() { NameValue = InputScopeNameValue.TelephoneLocalNumber }); } protected override void OnKeyDown(KeyEventArgs e) { if(Array.IndexOf(numeric,e.Key) == -1) { e.Handled = true; } base.OnKeyDown(e); // important, if not called the back button is not handled } } }
do not forgot to call the base.OnKeyDown method, otherwise your back button will be inefficient.
To use it in the mainpage : reference the namespace of the usercontrol:
xmlns:my="clr-namespace:WPNumericTextBox.Controls"
then use the control :
<my:NumericTextBox x:Name="NumTbx"/>
This solution is an improvement of the third : we add our control in a windows phone library so we can reuse it for another project !
To use it in the mainpage : reference the namespace of the usercontrol:
xmlns:my1="clr-namespace:WPControls;assembly=WPControls"
then use the control :
<my1:NumericTextBox Name="NumericTextBox"/>
I created a demo app :
The full demo source is available for download :
http://www.sambeauvois.be/Demos/WP7/NumericTextBox/WPNumericTextBox.zip
Links for this article :
How to link a dropdownlist and a detailview in both ways ?
Ie: I want my dropdownlist to be populated with a list of vendors, and if I select one of them I want to see the details of the vendor in the detailview.
Plus, if I add/delete/update a vendor in the detailview, I want the dropdownlist to be updated.
This kind of questions is often asked on different forums, here is my solution:
First we need a datasource, so for the demo we will create a simple vendor class in our DAL.
The vendor class has three properties : ID, Name and WebSite and one static method : “All” who allows us to retrieve a list of vendors.
We also need a manager class for these vendors, which will be in our BLL.
VendorsManager will contain the simple crud methods (Get, Insert, Update, Delete) and a “GetAll” method which simply call the DAL.Vendors’s “All” Method
Now that we have our datasource methods ready, we can create a webform named “DropDownDetailView.aspxâ€
The solution has to be like that:
In the aspx markup we’ll add an objectdatasource which will be used by the dropdownlist.
This objectdatasource will use the GetAll method from our BLL.
<asp:ObjectDataSource runat="server" ID="VendorsDataSource" TypeName="DataControls.BLL.VendorsManager" SelectMethod="GetAll"/>
Then we add the dropdownlist and configure it to use the objectdatasource.
<asp:DropDownList runat="server" ID="VendorsList" DataSourceID="VendorsDataSource" DataValueField="ID" DataTextField="Name" />
If you run the application you will have a dropdownlist populated with our vendors
Now we add a second objectdatasource with the same TypeName, and we set the SelectMethod, UpdateMethod, DeleteMethod and InsertMethod to use the methods of the VendorsManager’s methods.
<asp:ObjectDataSource runat="server" ID="VendorDetailDataSource" TypeName="DataControls.BLL.VendorsManager" SelectMethod="Get" UpdateMethod="Update" DeleteMethod="Delete" InsertMethod="Insert"/>
And because the GetMethod takes a parameter, we will say to the objectdatasource to take this parameter from the Selected value of the dropdownlist.
<SelectParameters> <asp:ControlParameter Name="id" ControlID="VendorsList" PropertyName="SelectedValue" Type="Int32" /> </SelectParameters>
So the complete objectdatasource will be
<asp:ObjectDataSource runat="server" ID="VendorDetailDataSource" TypeName="DataControls.BLL.VendorsManager" SelectMethod="Get" UpdateMethod="Update" DeleteMethod="Delete" InsertMethod="Insert"> <SelectParameters> <asp:ControlParameter Name="id" ControlID="VendorsList" PropertyName="SelectedValue" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource>
Now that we have our datasource, we can link it to a detailview.
So we create the detailview and tell him to use the datasource
<asp:DetailsView runat="server" ID="VendorDetail" DataSourceID="VendorDetailDataSource"Â />
If we run the application, we see that the detailview is filled with the details of the first vendor
Try to select another vendor in the list -> nothing happens!
It’s because we don’t cause a postback to the server to let him change the data.
To achieve that, we simply set the AutoPostBack property of the dropdownlist to true, so the dropdownlist is
<asp:DropDownList runat="server" ID="VendorsList" DataSourceID="VendorsDataSource" DataValueField="ID" DataTextField="Name" AutoPostBack="true"/>
Re-run the application and change the selected value of the dropdownlist.
Now the data in the detailview matches the selected vendor.
The first part of our need is achieved!
Now we want to be able to add, edit or delete vendors, so we set the detailview’s propertie AutoGenerateDeleteButton, AutoGenerateEditButton and AutoGenerateInsertButton to true.
And we don’t forget to set the DataKeyNames property to “IDâ€, because ID is the key for our vendors.
So now, the detailview looks like this:
<asp:DetailsView runat="server" ID="VendorDetail" DataSourceID="VendorDetailDataSource" DataKeyNames="ID" AutoGenerateDeleteButton="true" AutoGenerateEditButton="true" AutoGenerateInsertButton="true"/>
Run the application and try to add a new item
Now that the new vendor is inserted, look at the values in the dropdownlist
Arghh, the new vendor is not in the list !
It’s normal! We don’t refresh the dropdownlist yet!
To do that, we’ll add handlers for deleted, inserted and updated events.
The aspx markup of the detailview becomes
<asp:DetailsView runat="server" ID="VendorDetail" DataSourceID="VendorDetailDataSource" DataKeyNames="ID" AutoGenerateDeleteButton="true" AutoGenerateEditButton="true" AutoGenerateInsertButton="true" onitemdeleted="VendorDetail_ItemDeleted" oniteminserted="VendorDetail_ItemInserted" onitemupdated="VendorDetail_ItemUpdated"/>
and in the code-behind of the page :
protected void VendorDetail_ItemDeleted(object sender, DetailsViewDeletedEventArgs e) { Refresh(); } protected void VendorDetail_ItemInserted(object sender, DetailsViewInsertedEventArgs e) { Refresh(); } protected void VendorDetail_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e) { Refresh(); }
In each handler, I call the Refresh() method , and in this method we will rebind the dropdownlist:
private void Refresh() { this.VendorsList.DataBind(); }
Now, run the application, and redo the same test:
Now look at the dropdownlist:
And that’s it! The new vendor is in the list
Now, all the steps are processed!
Here is the complete final aspx markup
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DropDownDetailView.aspx.cs" Inherits="DataControls.DropDownDetailView" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Dropdownlist and detailview demo</title> </head> <body> <form id="form1" runat="server"> <asp:ObjectDataSource runat="server" ID="VendorsDataSource" TypeName="DataControls.BLL.VendorsManager" SelectMethod="GetAll"/> <asp:DropDownList runat="server" ID="VendorsList" DataSourceID="VendorsDataSource" DataValueField="ID" DataTextField="Name" AutoPostBack="true"/> <asp:ObjectDataSource runat="server" ID="VendorDetailDataSource" TypeName="DataControls.BLL.VendorsManager" SelectMethod="Get" UpdateMethod="Update" DeleteMethod="Delete" InsertMethod="Insert"> <SelectParameters> <asp:ControlParameter Name="id" ControlID="VendorsList" PropertyName="SelectedValue" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource> <asp:DetailsView runat="server" ID="VendorDetail" DataSourceID="VendorDetailDataSource" DataKeyNames="ID" AutoGenerateDeleteButton="true" AutoGenerateEditButton="true" AutoGenerateInsertButton="true" onitemdeleted="VendorDetail_ItemDeleted" oniteminserted="VendorDetail_ItemInserted" onitemupdated="VendorDetail_ItemUpdated"/> </form> </body> </html>
And the matching code behind
using System.Web.UI.WebControls; namespace DataControls { public partial class DropDownDetailView : System.Web.UI.Page { protected void VendorDetail_ItemDeleted(object sender, DetailsViewDeletedEventArgs e) { Refresh(); } protected void VendorDetail_ItemInserted(object sender, DetailsViewInsertedEventArgs e) { Refresh(); } protected void VendorDetail_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e) { Refresh(); } private void Refresh() { this.VendorsList.DataBind(); } } }
Links for this article :
As a .NET developper you may be tempted to create a custom exception class for each of your exceptions you throw.
But plenty of them are already present in the .NET framework.
If your need matches one of these Exceptions, use it instead of reinvent the wheel.
I generated a list of the available exceptions, you can consult it here.