Alin’s Blog

January 25, 2012

Using custom fonts in android. Bold, Italic, Regular… you name it!

Filed under: Android — alinberce @ 18:22
Tags: , , , , , , ,

As time has proven me, in Android many of the things I was used to make quite easy in .net, require a lot of manual coding. Using custom fonts does not make an exception… Everything depends on what you/your client wants to have in the app.

Brief intro regarding fonts.

First take a very good look at the font license. Of course, the best fonts, the handsome and good looking ones forbid free distribution. So in case you don’t want to have any legal issues, read carefully before using a certain font. Usually fonts are of two types: OTF stands for OpenType Font and TTF stands for TrueType Font (you can take a look at http://www.differencebetween.net/technology/difference-between-ttf-and-otf/ to see the difference between them). From what I have read around the web, they say that Android supports better TTF and is recommended that in case you want to use OTF to convert it. Personally I tried the both formats and all displayed well, so it’s up to you what type to use.

Setting things up. Put your coffee on your right…

The brief was very boring I know, but it was necessary. Now let’s settle our development environment. First, we need to use a free font. I have searched for an alternative to well known Myrian Pro from Adobe and recommendations went to Vegur. You can download it from: http://www.fontspace.com/arro/vegur . Please download the archive and take a look at it…

image

What in the name of God are those names you may say (as I did). That is the font indeed, but it is split into different files. So you’ve got Vegur-B 0.602 for Bold font, Vegur-R 0.602 for regular font and so on. When you create a project for android in Eclipse, you will see a folder called assets, make in assets new folder fonts and copy these two files in it and we’re done, fonts are added in our project. So simple, eh ?

image

How on earth do I use this font in my code ?

Let’s take a quick look at how a TextView is defined in an xml file.

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Regular TextView no typeface"
        android:textColor="#00FF00" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text"Regular TextView Monospace typeface"
        android:textColor="#00FF00"
        android:typeface="monospace" />

First TextView is plain and uses the default typeface. In the second TextView things are getting a bit complex as we have android:typeface attribute set to monospace. What does this mean ? The TextView will use Monospace font to display the text. Running the app will result in this:

image

I know what you are thinking… I’ll just replace monospace with my Vegur and we are done. Well, well, well… sorry to disappoint you, but there is no way we could use our custom font as a typeface straight from xml declaration. This is not cool. So all you code writing lovers, gather around as we need to dive into the wonderful world of custom controls.

Depending on your request there are several ways to do things, so we’ll take a good look and analyze/fix each one.

1.  I want a single TextView in my activity to use this font.

Maybe you have a logo text, or maybe you have some specific portion of text you need to make more obvious. In this case the solution is simple.

First add a new TextView in the main layout

<TextView
        android:id="@+id/txtOnlyOne"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="This TextView has our custom font"
        android:textColor="#00FF00" />

Go to main activity of the project, and within onCreate add this code:

Typeface tf = Typeface.createFromAsset(this.getAssets(), "fonts/Vegur-R 0.602.otf");
TextView tv = (TextView) findViewById(R.id.txtOnlyOne)
tv.setTypeface(tf);

image

Pretty simple and direct. We create the typeface in code and assign it to desired TextView. This may seem like a good solution in this case, but what if you face 20 TextViews ? It’s not so pleasant to find each one and assign the typeface to it. You could still try to do it this way, or you could go to next point…

2. I want the whoooooooooole activity to use this font.

Well, if setting it for a TextView was so simple…  setting it to all TextViews should be the same no ? The only thing that may give us trouble, is finding all the TextViews… so, why shouldn’t we look in all views and check? Take a look at this method:

private void overrideFonts(final Context context, final View v) {
    try {
      if (v instanceof ViewGroup) {
        ViewGroup vg = (ViewGroup) v;
        for (int i = 0; i < vg.getChildCount(); i++) {
          View child = vg.getChildAt(i);
          overrideFonts(context, child);
        }
      } else if (v instanceof TextView ) {
        ((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Vegur-R 0.602.otf"));
      }
    } catch (Exception e) {
    }
  }

Simply add this line, on activity after setContentView and see the results:

  overrideFonts(this, findViewById(android.R.id.content));

image

Wow… all TextViews look the same way, using our custom font. Good job. We should be fine, let’s go home and celebrate. But hey, what if…

3. I want the first and third TextView with bold font

Ah, piece of cake, I’ll just add android:textStyle=“bold” for them and everything should be fine. Run and see the results

image

Ups… what da’… no change, it still looks the same way, where is my bold setting gone?

And now we get back to intro where we say that font file is split into several files. We need somehow to make sure that our TextView considers the textStype attribute and acts according to it. The only way to achieve this goal, in a nice manner, is to create a custom TextView and handle our typeface change in it. To keep things short, as I see you are bored, here is our extended control:

public class MyTextView extends TextView {
    public MyTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyTextView(Context context) {
        super(context);
    }

    public void setTypeface(Typeface tf, int style) {
          if (style == Typeface.BOLD) {
              super.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/Vegur-B 0.602.otf")/*, -1*/);
          } else {
              super.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/Vegur-R 0.602.otf")/*, -1*/);
          }
    }
}

As you can see we intercept the setTypeface method, and depending of style value we assign our own custom typeface. To use it, simply add it in xml file

    <com.alinberce.MyTextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="This MyTextView has our custom font"
        android:textColor="#00FF00" />

    <com.alinberce.MyTextView
        android:id="@+id/txtOnlyOne"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="This MyTextView has our custom BOLD font"
        android:textStyle="bold"
        android:textColor="#00FF00" />

And finally we see it running and displaying the results as we wanted.

image

I personally use this as I don’t want to agglomerate my Activity code and allow me an easy way of changing the font for my entire app. You can simply put the “fonts/Vegur-B 0.602.otf” in a constant or a SharedPreference and when you change it, all you app will look different.

This post represents a resume of my questions on stackoverflow or answer found there. I just wanted to sum everything up and offer nuances of solutions based on everyone’s needs. I really hope you’ve understood it and will help you in the future. Please drop a comment if you liked it, or correct if I said something wrong.

You can find the source code of the article in this eclipse project : http://ifile.it/p0ovny3/FontsTutorial.src.zip

image

Compass VO for Android

Filed under: Android — alinberce @ 17:37
Tags: , , , , , ,

 

image

All you orienteering fans, gather around, I have a great announcement for you. Not an orienteering fan? No problem, after trying Compass VO along with Virtual Orienteering for Android you will be. I know what you were thinking when saw the app name “Oh boy, not another compass application”. The Android Market is full of compass applications, each having nice features and options. So, why a new one? That’s what I’ve asked the creators of the concept behind Compass VO. The answer is simple: it has some pretty neat features not found on other products that you’ll enjoy at max.

What makes Compass VO worth to try?

  • Use the popular 1, 2, 3 compass system along with this digital compass, the same as a real compass.
  • You can easily use an image of a map as a background. The image can be taken either from the phone’s Gallery or live with in-app integrated camera preview. But this is not all, after loading the map image you can manipulate it to suit your needs: rotate, zoom in and out, pan, everything is at your finger. The background remains saved and you can always update it, even after application is reopened.

image

  • Uses internal magnetic field and accelerometer sensor combined with GPS and wireless networks to offer accurate information. This allows you to choose if you want to use the magnetic heading or the true heading. All received information is available, depending on chosen theme.

image

  • Compass dial for target bearing and/or orienteering.

image

  • Multiple themes (Orienteering, Digital, Compass Rose, Mango graphics, Night, Android, many to come in the future) for each user’s taste, maybe you like a light theme or maybe a darker one… or why not the special Green robot theme

imageimageimage

  • No annoying ads, no pop-ups, no interruptions, no user spying.

I tried to keep permissions as few as possible. As you will see no “suspect” permissions like access your personal data or internet connection. So the ones that are needed are as follows:
Camera: used only on your request, with preview in order to take a photo of a map
Access fine location: used to calculate the Geographic North and offer Magnetic declination.
Wake lock: used to keep the screen on all the time. This is an option in Settings, but keep in mind that it uses a lot of battery.

      As a side note, please keep in mind that the accuracy of magnetic sensors in android powered devices is very variable. Based from manufacturer to manufacturer this can vary from pretty good accuracy to an unreliable one. You can always try to calibrate by holding the phone in front of you and moving it in a Figure-8 pattern, to see if it improves.

    Are you convinced to give it a try ? I sure hope so. Please take a look at About page in Settings. You can rate it in Android Market (5 stars please  ) or if you encounter any problems drop us an email and will do our best go fix it as fast as possible.
In the end, I must say I really enjoy working with the professional team from Just Windows Phone. Compass VO was made originally for Windows Phone Mango, carefully designed and implemented by them, and then ported by me on Android platform. I bet you wondered from what comes VO in the title? From Virtual Orienteering, this is the father project, Compass VO being a free tool to complete it. I invite you to also take a look at Virtual Orienteering community and the android application from the market.

Special thanks to:
 Virtual Orienteering – Find your way! – www.vorienteering.com

image

Just Windows Phone – www.just-windows-phone.com

image

Can be found in Android market at: https://market.android.com/details?id=com.vorienteering.compassvo

September 17, 2010

We’re in business. VOrienteering.com is alive and kicking. You’re welcome to join our community.

Filed under: Uncategorized — alinberce @ 17:32

Hi all. It has been a really long time since I posted something in here. In past months I’ve been very busy as I switched to the Dark Side Smile, I program in java now. More precisely in Android. It is a wonderful journey for me, and I hope that in the end it will worth the time.

  A few words… well, it’s all about nature, move, sport, tracks, gps, devices, android, iphone, winmo. Just go in there, make a track and… do it with the device in real world. You know it guys don’t you… real world with trees and stuff, nature… I’m talking to you programmer Open-mouthed smile   Unfortunately the Android client isn’t ready yet, but until the end of month you’ll be able to use it with your device. Everything is free.

The web site is www.vorienteering.com . Be our next friend, register (it’s really easy to do) and provide us feedback, ideas and problems. As you can see we are in beta version.

Here are some screens of Android client:

 

image  image  image

I feel some new tutorials on Android platform coming soon Smile 

Technorati Tags: ,,,

December 23, 2009

Deploying Silverlight WCF service from developement station to IIS

Filed under: Silverlight — alinberce @ 10:52
Tags: , ,

 

The beginnings…. 

I have created a Silverlight application that uses some data taken from an almighty SQL Server. To bring data I used Silverlight enabled WCF Services. The Visual Studio solution contains the Silverlight application project and the added Web site to display the Silverlight control.  The web application contains the WCF Service and the service is referenced in the Silverlight application project.

The Solution looks like this:

SilverlightWeb - the web application, contains a folder WCFServices in which I have Service.svc

SilverlightApp – Silverlight control that references Service.svc

When I ran the solution from within Visual Studio’s internal IIS server everything works fine, I can see the SQL data in the Silverlight control.

If I try to access the .svc file from the browser accessing the http://localhost:1487/WCFServices/Service.svc I can see a page with "You have created a service.", so it’s fine.

When I was ready with milestone one of the project I decided to give it a test-drive on the IIS production server . In order to deploy the solution to the IIS Production server I took the SilverlightWeb folder and copied it on the wwwroot folder. I created a Virtual Directory for SilverlightWeb folder. The .svc extension appears to be registered on the IIS. Before deploying I also modified the ServiceReferences.ClientConfig file, setting the endpoint address from

endpoint address="http://localhost:1487/WCFServices/Service.svc"

to

endpoint address="http://IIS Server’s IP address/WCFServices/Service.svc"

When I try to access from browser (http://IIS Server’s IP address/SilverlightWeb/TestPage.html), I can see the silverlight control, but when I press the button that calls the WCF Service nothing happens.

I tried to access the WCF service directly to see: http://IIS Server’s IP address/WCFServices/Service.svc  and gives me a File not found error

If I access using http://IIS Server’s IP address/SilverlightWeb/WCFServices/Service.svc I get a window where it says

<%@ ServiceHost Language="C#" Debug="true" Service="SilverligtWeb.WCFServices.Service" CodeBehind="Service.svc.cs" %>
 

The cursing…

In order to make the solution work on IIS I did everything I could find over the Google. I was really pissed off because WCF seemed such a fine concept but I couldn’t use it. It took me almost one week to find the answers… the good thing is that meanwhile I had other things to think about, rather than cursing. I have a straight rule: if it isn’t broken, don’t break it. Of course, the IIS server was fully used by a bunch of final users and I couldn’t risk making all kind of trial and error on it in order to make WCF service work. So, I made a full Backup and restore it on on PC. After all the hassle of restoring the image, driver install, network configuration… when everything was ready (took me 2 days) in 5 minutes I got the solution working. As my good friend, Emanuel said: It’s probably a 2 minute thing. Well, it was a simple thing. Emanuel also recommended me a great piece of software: Fiddler2. It is very useful to see what connections are being made from the browser, as it acts like a proxy between the browser and the network.

The solution…

Three baby steps were needed in order to solve the issue:

1.  Make sure that .Net 3 or 3.5 is installed on the IIS

2. Configure the IIS metabase to pass .svc files to ASP.NET and then on the WCF. The .svc was handled as static content.

Thank you Richard Blewett for these two steps.

3. A final step would be modifying the endpoint address (again) to be correct. When in Visual Studio internal IIS, there was no virtual directory created in order to run the project locally. When I deploy it on IIS I made a virtual directory so the endpoint address should be updated in order to have the correct path to .svc file.

endpoint address="http://IIS Server’s IP address/WCFServices/Service.svc"

to

endpoint address="http://IIS Server’s IP address/VirtualDirectoryMadeForSolution/WCFServices/Service.svc"

If still doesn’t work, please check to see if .svc extension is registered. If no, manually register it.

Well that’s all. I had to learn a little Silverlight. It is indeed a great technology that allowed me to make thing I could even think possible in a browser.

November 6, 2009

I’m a father…. Yupiiiiiiii

Filed under: Uncategorized — alinberce @ 20:43

   Well, I am very excited, today my wife gave birth of our daughter. In my country there is a serious issue with AH1N1 flu and I have problems getting to see them in the hospital. So, as you can guess, I am the happiest man on earth, thank God for making this wonder happen. Daria, my little angel, has 3.2 Kg and was born today at 10.15 am.

October 15, 2009

Using a web service straight from SQL Server 2005

Filed under: Uncategorized — alinberce @ 17:33
Tags: , , ,

Interesting idea with lots of potential. I managed to consume web services from Window Forms application,from ASP.Net web pages but never directly from a SQL Server Database. I’ve researched a little and I know that it can be done and how it can be done. So let us proceed then.

To be able to use the web service from SQL Server we will use a component called CLR (Common Language Runtime) which has been included since the 2005 version. Using this component, we will create a UDF (User Defined Function) within Visual Studio which will consume the web service and which will be used in a SQL Server Table Valued Function to get the results as a SQL table. It does sound kind of tricky but I’ll try to explain it step by step.

I will make this into 2 parts, one that will take place in Visual Studio 2005 and one that will take place in SQL Server Management Studio.

Part I – The Visual Studio side of the story

Everything starts with creating a new project in Visual Studio pf SQL Server Project type. Its name will be CLRWebService

image

Before creating the UDF object we need to get a reference to the web service. The web service I will use for exemplification is offered free by www.infovalutar.ro , a website owned by a friend of mine.

To add a reference right click on the name of the solution and choose from the menu the option Add web reference. In the window that appears, it he URL field write the web service’s address

http://www.infovalutar.ro/curs.asmx?wsdl

image

In the right site of the window you can observe all the methods offered by the service and the parameters required. In The Web reference name filed will rename it to infovalutar and will press the button Add Reference

After the window closes you can see in Solution explorer that the reference has been added.

image

Now we can create the UDF object. Add a new item to the solution:

image

As I said before, the template used will be User-Defined Function and it will have the name GetCursuriValutare. The main scope of this function will be to access the getall(Date) method of the web service and get the exchange rate for the date sent as parameter.

Before writing any code we must analyze and see what exactly this function must achieve:

  • it must be read only, since it only shows data
  • it will have a method to populate the data (GetCursuriValutare_FillRow)
  • will return a table that will contain the fields returned by web service’s method

Let’ start by defining the functions attributes using SQLFunction command

[SqlFunction(
       DataAccess = DataAccessKind.Read,
       FillRowMethodName = "GetCursuriValutare_FillRow",
       TableDefinition =   "IDCurrency NVARCHAR(10), " +
                           "Value float  "
       )
   ]

We have a method that returns the final result

public static IEnumerable GetCursuriValutare()
    {
        DateTime dt = DateTime.Now.AddDays(-1);
        return new Curs().getall(dt).Rows;
    }

Here we take care of the DateTime parameter requested. This method returns an object Of type IEnumerable for the web service Curs() contained in the namespace infovalutar.

The GetCursuriValutare_FillRow methods populates UDF the record set from the object Curs returned as IEnumerable

public static void GetCursuriValutare_FillRow(
        object CursObj,
        out SqlString IDCurrency,
        out SqlDouble Value
        )
    {
        DataRow r = (DataRow)CursObj;
        IDCurrency = new SqlString(r[0].ToString());
        Value = new SqlDouble(Convert.ToDouble(r[1]));
    }

The final piece of code should look like this:

using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Xml;
using CLRWebService.infovalutar;

public partial class UserDefinedFunctions
{
    [SqlFunction(
       DataAccess = DataAccessKind.Read,
       FillRowMethodName = "GetCursuriValutare_FillRow",
       TableDefinition =
      "IDCurrency NVARCHAR(10), " +
       "Value float  "
       )
   ]

    public static IEnumerable GetCursuriValutare()
    {
        DateTime dt = DateTime.Now.AddDays(-1);
        return new Curs().getall(dt).Rows;
    }

    public static void GetCursuriValutare_FillRow(
        object CursObj,
        out SqlString IDCurrency,
        out SqlDouble Value
        )
    {
        DataRow r = (DataRow)CursObj;
        IDCurrency = new SqlString(r[0].ToString());
        Value = new SqlDouble(Convert.ToDouble(r[1]));
    }

};

Because we managed to finalize the function we must now obtain the required dll files to be able to use it in SQL Server. A very important thing to mention here, the XML object aren’t automatically serialized so we need to do this our self. This is being done using a tool included in Visual Studio: sgen.

To automate things a little bit will use Solution’s Build events to tale care of serialization. Right click on Solution name -> Properties ->Build Events and in the Command line for the Post-build event add the following

“C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sgen.exe” /force “$(TargetPath)”

image

From the Build menu choose Build CLRWebService and pray that there will be no errors.

If everything went well, in the project folder should be 3 generated files:

image

If you have those files it means that the UDF creation is done. Go grab a snack and come back for the second step of this tutorial.

Step II – What does SQL Server has to say

To make things easyier will make a new folder on C:\ named CLRGetCurs in which we will copy 2 of the 3 generated files: CLRWebService.dll and CLRWebService.XmlSerializers.dll

Open SQL Server Management Studio, connect to the desired SQL Server instance and open a new Query. For exemplification we will use the AdventureWorks database.

use AdventureWorks
go
-- allows access from exterior
ALTER DATABASE AdventureWorks SET TRUSTWORTHY ON;
GO

--checking that the objects exists before creation
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'GetCursuriValutareWS')
   DROP FUNCTION GetProductWS
go
IF EXISTS (SELECT [name] FROM sys.assemblies WHERE [name] = N'XmlSerializers')
    DROP ASSEMBLY [XmlSerializers]
IF EXISTS (SELECT name FROM sys.assemblies WHERE name = 'GetCusturiValutareCLR')
   DROP ASSEMBLY GetProductCLR
GO

-- create assemblys for the  2 dll files from folder CLRGetCurs
Create ASSEMBLY GetCusturiValutareCLR FROM 'C:\CLRGetCurs\CLRWebService.dll'
WITH PERMISSION_SET = External_Access

CREATE ASSEMBLY [XmlSerializers] from
'C:\CLRGetCurs\CLRWebService.XmlSerializers.dll'
WITH permission_set = SAFE
GO

We are one step closer to the finish line. We only need to create a Table Valued Function that makes use of the external UDF function:

CREATE FUNCTION GetCursuriValutareWS() 

RETURNS TABLE (
IDCurrency NVARCHAR(10),
Value FLOAT
   )
AS EXTERNAL NAME GetCusturiValutareCLR.UserDefinedFunctions.[GetCursuriValutare]
GO

And now, let us enjoy the results of our work:

image

Impressive, I was really amassed to see the web service result in the SQL Server Management Studio. It makes you feel you can do anything you want. I wonder if these UDF functions can be used to alter the content of the database ? Hmm… I’ll check and see.

A good source of information for this article I’ve found on www.databasejournal.com.

I hope you enjoyed this short tutorial. Until next time, Happy coding.

P.S. I know I’ve started a series of tutorials regarding n-tier concepts. Now I left this aside and I started learning about DDD (Domain Driven Design) and how these concepts can be implemented using C# techniques. Still layers but in a more effective “proven” way and a more documented concept.  I would like to THANK Emanuel for guidance and for pointing me into the right direction. There will be some interesting tutorials so stay put.

For the romanian version of the tutorial check this address http://www.infovalutar.ro/howto/sqlserver.aspx

September 18, 2009

How to make a business rule in BLL and use it wisely

Filed under: WPF — alinberce @ 21:08
Tags: , , , , ,

Based on previous tutorial we will try to make a business rule for user name. The simplest rule possible is that the Username must not be empty. We must be able to check for this in the BLL and, in case of error, display a message in UI. Sounds simple ? Now let’s make it.

In this case it’s a simple rule, but just imagine that for our method GetUser(…) we can have many validations (Username must be at least 5 characters, Password can’t be blank… etc) so, after checks are being done a list of errors could appear, this means we must have possibility to store all errors and make them available to the UI. For achieving this purpose we’ll create a new Class called BusinessRule in which we will store some information regarding the failed checks:

public class BusinessRule
    {
        private String _RuleType;
        public String RuleType
        {
            get { return _RuleType; }
            set { _RuleType = value;}
        }

        private String _Message;
        public String Message
        {
            get { return _Message; }
            set { _Message = value; }
        }

        private String _Property;
        public String Property
        {
            get { return _Property; }
            set { _Property = value; }
        }

        public BusinessRule()
        {
        }

        public BusinessRule(String _RuleType, String _Message, String _Property)
        {
            RuleType = _RuleType;
            Message = _Message;
            Property = _Property;
        }
    } 

We could have different type of checks which will return different type of messages: Warnings, Errors or Info. This will be stored in RuleType. The message is pretty self explanatory, the message displayed on rule fail. The property will store the property name that failed the checks (Username in our case) and will help the UI to focus the problematic controls.

Now let’s get back to the userBo class and make some changes to use the BusinessRule class.

public List<BusinessRule> BrokenRules = new List<BusinessRule>();  

        public User GetUser(string UserName)
        {

            if (string.IsNullOrEmpty(UserName))
            {
                BrokenRules.Add(new BusinessRule("Error","User name cannot be empty","UserName"));
                BrokenRules.Add(new BusinessRule("Warning", "You have 3 more retries", "UserName"));
                BrokenRules.Add(new BusinessRule("Info", "User name has a minimum length of 5 characters", "UserName"));
            }

            if (BrokenRules.Count.Equals(0))
            {
               UserDO usrDO = new UserDO();
               return  usrDO.GetUser(UserName);
            }
            else
                return null;
        }

If check fails, all the errors will be added to the BrokenRules list. This list is Public, so it can be used by the UI.

Making the UI use the BrokenRules list

Imagine that a list of BrokenRules will be available for all classes in UserBO, so we’ll need to make a window and provide a datasource to it programatically. The layout of the window will be as follow:

image

<Window x:Class="NoiaUI.Message"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Message" Height="300" Width="300" WindowStartupLocation="CenterScreen">
    <Window.Resources>
        <CollectionViewSource x:Key="MessagesSource"/>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="Atentie" FontSize="14" Margin="5"/>
        <ListBox Name="lstMessages"  ItemsSource="{Binding Source={StaticResource MessagesSource}}" Grid.Row="1">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Margin="5"  Source="{Binding Path=Image}" Stretch="Fill" Width="16" Height="16"/>
                        <TextBlock Margin="5" Text="{Binding Path=Message}"/>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ListBox>
        <Button Name="btnContinue" Grid.Row="2" MaxWidth="100" MaxHeight="25" Click="btnContinue_Click" Margin="4">Continue</Button>

    </Grid>
</Window>

We declare a CollectionViewSource as a Window Resource that will be the ItemsSource of the listbox. Here you can see something interesting, in the ItemTemplates I added a StackPanel in which we have 2 controls, a Image and a Textbloc. To make the window better looking, will add some icons for RuleTypes, it’s much nicer to see a Error icon instead of the text “Error”.

In the cs file we take care of everything

public partial class Message : Window
    {
        public Message()
        {
            InitializeComponent();
        }

        private class MessageFormat
        {
            public BitmapImage Image { get; set; }
            public string Message { get; set; }
            public string Property { get; set; }
        }

        public void SetMessagesSource(List<BusinessRule> lstMessages)
        {
            List<MessageFormat> finalMessage = new List<MessageFormat>();
            DirectoryInfo ImageDir = new DirectoryInfo(@"..\..\Images");

            foreach (BusinessRule br in lstMessages)
            {
                FileInfo fi = new FileInfo(@"..\..\Images\"+br.RuleType+".png");
                Uri uri = new Uri(fi.FullName);
                finalMessage.Add(new MessageFormat { Image = new BitmapImage(uri), Message=br.Message, Property=br.Property });
            }

            CollectionViewSource MessagesSource = (CollectionViewSource)this.Resources["MessagesSource"];
            MessagesSource.Source = finalMessage;

        }

        private void btnContinue_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }

A class, MessageFormat is used to store the ruleType as BitmapImage. A public methon, SetMessageSource, is used to read the image files, add the entire content to the finalMessage list and set the CollectionViewSource source. In this way, we instantiate the windows, call the SetMessageSource method and then display it on the screen.

Let’s see how to use it in real life enviroment. In the Login window, btnLogin click event will look like this:

private void btnLogin_Click(object sender, RoutedEventArgs e)
        {

            UserBO usrbo = new UserBO();
            User usr = usrbo.GetUser(txtUserName.Text);

            if (usr == null)
            {
                if (usrbo.BrokenRules.Count.Equals(0))
                {
                    MessageBox.Show("Wrong username");
                }
                else
                {
                    Message msg = new Message();
                    msg.SetMessagesSource(usrbo.BrokenRules);
                    msg.ShowDialog();
                }
            }
            else
                MessageBox.Show("Wellcome " + txtUserName.Text);
        }

Run it, don’t type anything, just press the login button. The window should look like this:

image

The app must not allow to continue until the BrokenRules list is empty. Furthermore, based on property field in list, we could set focus to controls that failed checks. I hope you enjoyed this tutorial. Until next time, Happy coding.

And of course  the video, this time in HD ;)

September 17, 2009

WPF N-Tier using Entity Framework

Filed under: WPF — alinberce @ 21:35
Tags: , ,

Noia development has begin with baby steps. Right now I am trying to make a application core that will support further changes very easy. Today we are going to learn how to make layer for application and how to make them communicate. As you’ve learned so far about me I won’t give many details and explanations, the main purpose is to get the result needed as fast as possible. This being said, let’s begin our tutorial.

Let’s start by creating a new solution called Noia. In this solution we will have 4 projects as follow:

  • NoiaDAL – represents the Data Access Layer. Project type Class Library
  • NoiaBLL – represents the Business Logic Layer. Project type Class Library
  • NoiaUI – will take care of User Interface layer. Project type WPF Application
  • NoiaEF – which will contain Entities. Project type Class Library

Also, we will make a new folder NoiaDB in which we will copy the NoiaDB.sdf (SQL Server CE database).

In order to make this layers communicate, we must create the references between them:

  • In NoiaUI create reference to NoiaEF
  • In NoiaBLL create references to NoiaDAL and NoiaEF
  • In NoiaUI create references to NoiaBLL and NoiaEF

In the NoiaED we will add a new item of type Ado.Net Entity Data Model named NoiaEntityModel.edmx. When ask the Model Content we will choose Generate from database and we’ll create a new connection string pointing to the NoiaDB.sdf file. The generated connection string will look like:

metadata=res://*/NoiaEntityModel.csdl|res://*/NoiaEntityModel.ssdl|res://*/NoiaEntityModel.msl;provider=System.Data.SqlServerCe.3.5;provider connection string="Data Source=C:\Noia\NoiaDB\NoiaDB.sdf"

After the model is generated we can see all the entities created. We will rename all the be singular. I don’t want to have a object Users, I want to have a object User. Also, in properties for each entity we will rename the Entity Set Name from UserSet to Users and so on, for all the entities that require it. At the end, it should look like this:

image

What I want to achieve in this tutorial is to be able to create a login screen and check if the user name provided by UI is valid or not. The information will travel between all layers forth and back. Please remember that each layer will have it’s unique characteristics and none of the layers will overlap.

NoiaDAL (Data Access Layer)

In DAL we will need to have a class for each entity we want to use. For our particular example we will add a new class and name it UserDO (from User Data Object). In this class we must have a method to search for a user based on the user named taped by the front user. In searching for the user we will use a Linq statement. Complete class code is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NoiaEF;

namespace NoiaDAL
{
    public class UserDO
    {
        public User GetUser(string UserName)
        {
            NoiaDBEntities ne = new NoiaDBEntities();

            var usr = from u in ne.Users
                  where u.UserID == UserName
                  select u;

            return usr.FirstOrDefault();
        }
    }
}

In order to be able to use the Entities we must add a reference at the project to System.Data.Entities. This pretty much makes the job done in the DAL.

NoiaBLL (Business Logic Layer)

As in DAL, in here we will have another class for User, in this case it will be named UserBO (User business object). Because the UI layer must not access DAL directly, the BLL will be an intermediary, and after validations and checks, the BLL will decide if will ask the DAL for information or provide direct feedback to the UI if validations failed. Because validation is the scope of the next tutorial, the UserBo will only redirect the request to DAL. Again, we must add a reference at the project to System.Data.Entities.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NoiaDAL;
using NoiaEF;

namespace NoiaBLL
{
    public class UserBO
    {
        public User GetUser(string UserName)
        {
                UserDO usr = new UserDO();
                return usr.GetUser(UserName);
        }
    }
}

NoiaUI (User Interface Layer)

We will create the login window. It must contain two textboxes for user input (one for User name one for Password) and a Login button. Add a new Windows (WPF) in NoiaUI project and name it Login

<Window x:Class="Noia.Login"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Login" Width="370" Height="120" Background="#185d7c" WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Label Name="lblUserName" Grid.Row="1" Grid.Column="0" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" >User name</Label>
        <Label Name="lblPassword" Grid.Row="2" Grid.Column="0" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5">Password</Label>
        <TextBox Name="txtUserName" Grid.Row="1" Grid.Column="1" MinWidth="200" Margin="5"></TextBox>
        <PasswordBox Name="txtPassword" Grid.Row="2" Grid.Column="1" Margin="5"></PasswordBox>
        <Button Name="btnLogin"  Click="btnLogin_Click" Grid.Row="2" Grid.Column="2" MaxWidth="50" MaxHeight="25">Login</Button>
    </Grid>
</Window>

The login button click event must communicate with the BLL and ask for data.

  private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            UserBO usrbo = new UserBO();

            User usr = usrbo.GetUser(txtUserName.Text);

            if (usr == null)
               MessageBox.Show("Wrong username");
            else
                MessageBox.Show("Wellcome " + txtUserName.Text);
        }

There are a few more things that need to be done: add a reference at the project to System.Data.Entities. Copy the App.Config file from NoiaEF to NoiaUI because we need the connection string. Set in App.xaml the startup window to login

<Application x:Class="NoiaUI.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Login.xaml">
    <Application.Resources>

    </Application.Resources>
</Application>

Run it and see the result… it should work like a charm

image

Next time we shall see how to make a business rule in BLL and how to send error list from BLL to UI. It will be interesting.

P.S. Very important note: it seems that there is a problem for Linq to Entity access the SQL CE Database file with the existing SP1. In order to make things work, you must uninstall SQL CE SP1 and install this hot fix: http://support.microsoft.com/kb/958478

And the videos… as you can hear I was pretty tired when making them, so a lot of ufffs and offfs :)

September 11, 2009

NOIA – Planning and analyze. The beginning…

Filed under: WPF — alinberce @ 20:03
Tags: , ,

    What does NOIA stand for ? NOIA is “Not Another Invoice Application”. Pretty explanative what it should do: a application for invoices and stocks which will deal with input and output, in a small level CRM, goods stock and payments.  The reason why I mention this is because while developing it, I will make a chain of tutorials describing each important step in development. As I will learn I will share knowledge.

Technical specifications

     Because it’s not either big size or complex the platform used for development will be Visual C# 2008 Express edition. The data sources will be two, SQL Server 2008 Express Edition and SQL Server Compact Edition 3.5. Those two database systems are suitable for most cases, for small to medium clients.

Thank you Microsoft for providing a free tools to developers.

Architecture

The architecture will be layered designed, so long live the n-tier. Main goals to achieve will be:

  • Changing one layer of the system should have a minimal impact over the rest of the layers. This will help maintenance, bug fixing and unit testing. It also makes the architecture more flexible
  • Unrelated components should be loosely coupled
  • Separation between User interface, Business objects and Database

image

Each layer will be developed as follow:

- Presentation Layer: Windows Presentation Foundation (WPF) and C#

- Business Objects Layer: C#

- Data Access Layer: C# and Linq   The database will contain only a few tables needed for fresh start (like Users, Companies etc.). The rest of the tables will be added as the development progresses.

The interface

     I am planning to make a extremely user friendly interface. I give a big deal about user pleasing, this makes the app sale. Just imagine that by my design flaw, a user must lose one second each time he saves an invoice (a freaking’ message box maybe), for a number of 3000 invoices/month there will be a lose of time around 1 hour. As I am a big fan of n-tier architecture, also, I am a big fan of outlook interface. This means the interface will have a very outlookish style. Plus some other enhancements as they come along.

image

         As a friend used to say, I’ve made a map to the user so it won’t get lost. This isn’t really true, but the workflow could help and it would be easier to go to a certain operation if remembered visually. The New/Save/Delete won’t be as in the image, there will be a combo box so that the user could select company or date or stuff like this. The upper image is a WIP (Work in Progress) so it can be changed. It may seem very colored now, at the end will have a more professional look.

This was a pretty boring post, even if I tried to make it as short as possible. If you have any suggestions please send them.

Until next time we “meet”, Happy coding.

P.S. – I would like to take a moment and THANK Cristi for help, support and ideas. So, thank you man.

August 31, 2009

SQLtoCS Class Generator – an SQL Table to C Sharp class generator.

Filed under: WPF — alinberce @ 18:47
Tags: , ,

Well, I’m back and I’m bad… as someone used to say. I’m really not that bad, but, for sure I know more. Because I’ve started to work on a new project for a customer of mine I felt the need to develop a tool to help me do stuff faster. One big pressure came from the fact that I develop this app in my free time which isn’t really that much. So while eating, sleeping, rebuilding house, staying with my wife, waiting for our unborn little girl, I managed to crop some lines of code. I also finalized reading a WPF book from start till last page. And man… I must say it again: WPF Rocks!!! Tananana it rocks.

What does this app do you ask: in nontechnical words, it does what I hate do do (repeated  work) :) in technical words it creates two classes for an Sql Server table. I’ve always been a fan of nTier architecture and the way WPF and C# works it this concept pleases me. And in big lines, this program does the business layer (Business objects) of a nTier architecture. Or at least, this is what I like to think it does.

Here is a screenshot:

Capture

The classes are generated in a few seconds. Just enter the credentials for the SQL Server or SQL CE connection, select Database and the table and press the Generate button. There are a few customizable parameters: class name, collection name and the namespace. The cs classes are saved in the exe’s directory.

The program detects what keys (PK and FK) are contained by the table and generates methods based on them.There are a lot of tools that do this on the net.  I’ve tested quite a few. There was always something bothering me and this is the main reason I started doing one for myself.

Please take your time and test it. If you have suggestions, please sent it to me.

UPDATE: The application can be downloaded from here: SqlToCs

A short, bad quality Youtube presentation:

Ah,  and about that PayPal button.. hehe… Donations are never required but they are more than welcomed.

Next Page »

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.