Cedric Ascoop's Bloggings

|

SharePoint, .NET, C# and more…

Unable to set margin on non modal FloatableWindow

Posted February 20th, 2013

Today I was having some problems with the FloatableWindow in my Silverlight project.

What was the problem?
I was already using the control for a while but now I needed to implement a system where you have the possibility to open multiple (non-modal) popups.
Doing this with default settings of the FloatableWindow gave me the problem that all the dialogs where placed on top of each other (like following image).

This is not very useful. So I wanted to create a cascade of dialogs. There is a possibility to set the margin of the dialog with following code:

dialog.Margin = new Thickness(100, 100, 0, 0);

This code works perfectly with the ShowDialog() function for modal dialogs. But when you are creating non-modal dialogs the margin is not working.

Next I will explain what you need to change to get this working.

You can download the source code for the FloatableWindow from CodePlex:
http://floatablewindow.codeplex.com/

Include the project in your Silverlight project.
Open the FloatableWindow.cs file.
Change the ChildWindow_SizeChanged method to the following code:

private void ChildWindow_SizeChanged(object sender, SizeChangedEventArgs e)
{
    if (this.Overlay != null)
    {
        if (e.NewSize.Height != this.Overlay.Height)
        {
            this._desiredContentHeight = e.NewSize.Height;
        }

        if (e.NewSize.Width != this.Overlay.Width)
        {
            this._desiredContentWidth = e.NewSize.Width;
        }
    }

    if (this.IsOpen)
    {
        this.UpdateOverlaySize();
    }
}

From now on the margin setting will also work for non-modal dialogs.



Create Radar chart from Database

Posted August 25th, 2012

Last I was asked to create a proof of concept for creating a radar chart based on some scores a user got on a test. The test is devided in categories and for each category the user gets a score.

First I created the database and it looked like this:

image

With this database I tried to create a radar chart via the Microsoft Reports (created via design mode in Visual Studio 2012). But there I had not much luck creating the chart. Whatever configuration I tried, the chart was never wat I expected it to be. After a while I gave up creating the chart via the design mode and tried to create the chart in code. Here I was more lucky.

The code to create the chart for this database looked like this:

var xValues = new string[] { "Category1", "Category2", "Category3", "Category4", "Category5", "Category6" };
using (var ctxt = new SoftwareFactory_ChartingEntities())
{
    var data = ctxt.Results.Select(x => x);
    foreach (var dataItem in data.Select(x => x.UserName).Distinct())
    {
        var dataForUser = data.Where(x => x.UserName.Equals(dataItem));
        foreach (var userItem in dataForUser)
        {
            Chart1.Series.Add(dataItem);
            var yValues = new List();
            yValues.Add(userItem.Category1);
            yValues.Add(userItem.Category2);
            yValues.Add(userItem.Category3);
            yValues.Add(userItem.Category4);
            yValues.Add(userItem.Category5);
            yValues.Add(userItem.Category6);
            Chart1.Series[dataItem].Points.DataBindXY(xValues, yValues);
            Chart1.Series[dataItem].ChartType = SeriesChartType.Radar;
            Chart1.Series[dataItem].IsValueShownAsLabel = true;
            Chart1.Series[dataItem].IsValueShownAsLabel = true;
            Chart1.Series[dataItem].ChartType = SeriesChartType.Radar;
            Chart1.Series[dataItem].Color = GetRandomColor();
            Chart1.Series[dataItem].BorderWidth = 2;
            Chart1.Series[dataItem]["AreaDrawingStyle"] = "Polygon";
            Chart1.Series[dataItem]["RadarDrawingStyle"] = "Line";
        }
    }
}

Chart1.ImageType = System.Web.UI.DataVisualization.Charting.ChartImageType.Jpeg;
Chart1.ChartAreas.Add(new ChartArea());
Chart1.ChartAreas[0].Area3DStyle.Enable3D = false;

Chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.LightGray;
Chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.LightGray;

When running the application (in my case a website) the chart looked like this:

image

After succeeding in creating the chart programmatically I tried again with the Visual Studio Reporting. And suddenly I found my mistake. The problem was not in the configuration, the problem was in the database.

Apperently the VS Reporting cannot handle it when each category is another column in the database. I recreated the database in another way so that my database looked like this:

image

And voila. My problem was solved.

My designer configuration looked like this:

image

 

So do not always blame the Reporting itself (like I did). In my case it was the database.

Hopefully this post will help you shorten your search for a solution.

Printing API

Posted August 7th, 2012

Last at work I had the following request for the application:

“We want a printing mechanism, but the default Internet Explorer printing is not enough. We only want that specific part of the website”.

For the record, the application here is a Silverlight application. The application contains navigation windows that may not be added to the printed version of the control.

And then I started looking at the Printing API. Here you have the possibility to isolate a particular FrameworkElement that you want to print. Hereby it is possible to exclude all the navigation controls from the printed page.

I created a test application that looks like this:

image

In this example you can see a MainWindow with some buttons and a canvas. In that canvas are some labels and a usercontrol.
The xaml for this Window looks like this:

<grid background="White" x:name="LayoutRoot">
    <button name="btnPrintEverything" click="btnPrintEverything_Click" width="92" verticalalignment="Top" margin="12,12,0,0" horizontalalignment="Left" height="23" content="Everything">
    <button name="btnPrintContent" click="btnPrintContent_Click" width="82" verticalalignment="Top" margin="110,12,0,0" horizontalalignment="Left" height="23" content="content">
    <button name="btnPrintUserControl" click="btnPrintUserControl_Click" width="93" verticalalignment="Top" margin="198,12,0,0" horizontalalignment="Left" height="23" content="UserControl">
    <canvas margin="0,41,0,0" name="cvContent">
        <my:silverlightusercontrol x:name="silverlightUserControl" width="162" height="141" canvas.top="36" canvas.left="135" />
        <sdk:label width="108" height="30" content="Example1" name="label1" canvas.top="6" canvas.left="12" />
        <sdk:label width="108" height="30" content="Example2" name="label2" canvas.top="36" canvas.left="12" />
        <sdk:label width="108" height="30" content="Example3" name="label3" canvas.top="72" canvas.left="12" />
        <sdk:label width="108" height="30" content="Example4" name="label4" canvas.top="108" canvas.left="12" />
        <sdk:label width="108" height="30" content="Example5" name="label5" canvas.top="147" canvas.left="12" />
    </canvas>
</grid>

Now i tried to print 3 versions of this application.

The first version was to print everything on the screen. Here I used the Grid FrameworkElement ‘LayoutRoot’.
The second version was to print the content of the screen (everything expect from the top buttons). Here I used the canvas ‘cvContent’.
And the last version was to print only the userControl (the green part). Here I used the ‘silverlightUserControl’ name.

The code to accomplish this looks like this:

private void btnPrintEverything_Click(object sender, RoutedEventArgs e)
{
    Print("Everything", this.LayoutRoot);
}

private void btnPrintContent_Click(object sender, RoutedEventArgs e)
{
    Print("Conten", this.cvContent);
}

private void btnPrintUserControl_Click(object sender, RoutedEventArgs e)
{
    Print("UserControl", this.silverlightUserControl);
}

private void Print(string documentTitle, FrameworkElement element)
{
    var docToPrint = new PrintDocument();

    docToPrint.PrintPage += (s, args) =>
    {
        args.PageVisual = element;
    };

    docToPrint.Print(documentTitle);
}

The result looks like this (3 versions):

image  image  image

TechEd Europe

Posted July 2nd, 2012

Last week I was at TechEd Europe. This year the event took place in Amsterdam (Netherlands).

For me it was the first time that I attended TechEd and it was a great experience. Saw some great sessions about the new Visual Studio 2012 and Windows Azure.

Now I’m back home and trying out some things I saw there. So in the next weeks you will see some more activity on my blog. I will post all my positive (and negative) experiences with the new features in Visual Studio.

The first thing that I did was creating a free Team Foundation Service account. You can create an account for free and I think Microsoft said that there will always be a free version of the TFService. You can create your own account at http://tfspreview.com/

The second thing I did was installing the new Windows 8 RC on my laptop (as my main operating system). I installed it 3 days ago and until now I’m still really happy with the change. The new metro style apps look very cool. My laptop is not touch enabled but still a great experience with the metro apps. Another thing that I noticed and was very happy to see is the default sync with google accounts (also Calendar, contacts, …).

Some things I will try next:

  • Create my own metro style app
  • Create a Windows Azure account
  • Install Windows Server 2012 RC

Parameter from SubWindow to MainWindow via Event

Posted January 30th, 2012

Last I was asked if it was possible to create communication between 2 windows and give a parameter with the event instead of firing an event and check manually the value of the property in the SubWindow.

And of course there is a solution to that problem.

The solution for this is by making use of a Delegate.

The problem with the standard event is that you can’t give extra parameters with the event. Standard you only have the Sender and the EventArgs. If you want to pass an extra parameter you need to create a delegate.

In this example I make use of a simple WPF application with a MainWindow and SubWindow. The MainWindow will create an instance of the SubWindow and when I change the value of the TextBox in the SubWindow the value of the label in the MainWindow will change with it.

First of all we need to create a new WPF project.
You can do this via ‘File –> New –> Project’ and select ‘WPF Application’ from the list of templates.
After you created the project you can add a new WPF Window to your application called SubWindow.

Than we can start coding.

The first thing you need to do is create an event on the SubWindow screen.

The interface for the SubWindow contains a textbox (for the input of the user) and a button (to launch the event).

image

In the code behind of your SubWindow you need to create delegate and an event property.
In the Click event of the button you can launch the event with the inputValue fo the textbox as a parameter.

!Remark: Best practice is to check if the event is null because if no screen has subscribed to the event you will get an error.

So by implementing this your code should look like this:

public partial class SubWindow : Window
{
    public delegate void CustomEvent(string inputValue);
    public event CustomEvent SubmitEvent;

    public SubWindow()
    {
        InitializeComponent();
    }

    private void btnSubmit_Click(object sender, RoutedEventArgs e)
    {
        if (SubmitEvent != null)
            SubmitEvent(txtValue.Text);
    }
}

After implementing the SubWindow we can now implement our Button_Click event of the MainWindow.

Here in the Button event we will create an instance of the SubWindow and subscribe to the event.

By doing this the code of your MainWindow should look like this:

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

    private void btnNewScreen_Click(object sender, RoutedEventArgs e)
    {
        SubWindow subwindow = new SubWindow();
        subwindow.SubmitEvent += new SubWindow.CustomEvent(ShowSubmittedInputValue);
        subwindow.Show();
    }

    public void ShowSubmittedInputValue(string submittedValue)
    {
        lblInputValue.Content = submittedValue;
    }
}

And now when you run the application, create an instance of the SubWindow and submit a value, the value will be shown in the MainWindow trough the use of an event with parameters.

image

Move website to subfolder

Posted December 11th, 2011

Recently I was creating a website on my computer (localhost). There I could work with paths that looked like this:

  • /Styles/images/image.png

This works perfectly when running it on my local pc. There the website structure looks like this:

  • http://localhost/
    • http://localhost/Styles
      • http://localhost/Styles/images
        • http://localhost/Styles/images/images.png

But when I tried to copy it to my server it didnt work.

The problem was that the website I build was actually a subfolder of an existing application. So I had the problem that all my paths were wrong.

The structure of my server looks like this:

  • http://localhost/
    • http://localhost/App1
      • http://localhost/App1/Styles
        • http://localhost/App1/Styles/images
          • http://localhost/App1/Styles/images/images.png

From now on I always work with the following code. This guarantees that the path is created at runtime and always right.

<img src="<%= Page.ResolveUrl("~") %>Styles/images/image.png" />

You can see in the code that the actual path of “~” is looked up at runtime. This keeps my application running in both my Visual Studio (where I don’t have the subfolder problem) and also on the server where it is a subfolder.

So from now on I automatically make use of this mechanism so that, when changing the application to a subfolder at a later time, it don’t give me the same problem.

 

Hopefully this can save you some time as well.

Exception handling (logging) via elmah

Posted November 22nd, 2011

When developing my applications I was looking for a global way of handling my exceptions.

There are some packages you can you for handling your exceptions.
First I used the Enterprise Library Exception Handling Block but today I changed from the Enterprise Library to another library called elmah.

In the next few minutes I will explain how to use the elmah package to handle and log your exception to a database.

First of all for our example I created a new Web Application. (In my case it is called ElmahExceptionHandling).
After creating the project I created an error page that will be used to redirect to that gives a nice and userfriendly message to the user. There I return the current date (+time) and the message that the users can call the helpdesk to examine their problem by giving this date. With that date the helpdesk can take a look in the database or at the elmah.axd file to check what the error message was.

After creating the Error page we will redirect to it in the Application_Error method in the global.asax. That is the method that is called when the application gets an exception.
By making use of the global.asax error method we don’t use specific exception handling in our application (so we never use a try catch block, unless we want some specific handling in a specific method).
To make our application redirect to the Error page when needed we add following code to the global.asax:

void Application_Error(object sender, EventArgs e) 
{ 
	// Code that runs when an unhandled error occurs 
	Response.Redirect("Error.aspx"); 
}

Now we need to make use of the NuGet package called Elmah to catch and handle our exceptions.

We will need to add ‘elmah’, ‘elmah.corelibrary’ and ‘elmah.sqlserver’. This last one is needed to create the sql tables to log all your exceptions to the database.

image

You will see that there is a App_Readme folder created into your project. There is a .sql file that will create the elmah table that is needed.

So next we will create the database.

You can take an existing database or create a new one and execute the script. I create a database ElmahExceptions and created there (through the sql script) the ELMAH_Error table. My database looks like this:

image

Now that our database is created we can set our connectionstring and create our web.config changes.

You will see that in the web.config file there is a line added:

<add name="elmah-sqlserver" connectionString="Data Source=****;User ID=****;Password=****;Initial Catalog=****;" providerName="System.Data.SqlClient" />

You need to change this to your database connectionstring. After changing my connectionstring looks like this:

<add name="elmah-sqlserver" connectionString="Data Source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=ElmahExceptions;" providerName="System.Data.SqlClient" />

To test this exception handling I put following code in the default.aspx page:

protected void Page_Load(object sender, EventArgs e)
{
	throw new Exception("TestException");
}

This wil create a new exception and the site will redirect to Error.aspx with the userfriendly message. My error page looks like this:

image

Now we can go to our “elmah.axd” page. Here we get an overview of all the errors. Now there will be an error for our own exception. The page will look like this:

image

And of course the error will also be logged in our database. If we take a look at the database we can see a new record that looks like this:

image

And so far my way of handling and logging my exceptions.

MVC 3 problems validating a decimal

Posted October 22nd, 2011

Last I was doing some MVC3 development but I kept on having validation problems with my forms.
My form looked like this:

image

I don’t know if you see my problem already but I had some problems validating my decimal.
When I submitted my form I always get the following error message: The field Max. aantal uren per VTE must be a number.
After a while I discovered what the problem was. I live in Belgium and here we write our numbers like 1000,1 . By default MVC3 only can parse this number written like 1,000.1 (other culture than nl_BE).
The nl_BE culture is not (yet) implemented in MVC3 but I found a workaround for this problem.

You can extend the jQuery validation with an extra script.
I used following javascript method to solve my validation error.

jQuery.extend(jQuery.validator.methods, {
    date: function (value, element) {
        return this.optional(element) || /^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value);
    },
    number: function (value, element) {
        return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value);
    }
});

In this code you can see that I changed the validation method for date and number. In this case it is the number function that solved my problem.

Hopefully I can save the people who are writing applications for this type of culture some time searching out the scripts.

Define 2 keys in an MVC3 model object

Posted October 22nd, 2011

Last I was converting an application into MVC3. But when I came to the point where I needed to create an object that contained 2 keys. I could not do this with following code:
I always received the error message: Unable to determine composite primary key ordering for type ‘Project.Models.ModelObject’. Use the ColumnAttribute or the HasKey method to specify an order for composite primary keys.

public class ModelObject
{
	[Key]
	[Required]
	public decimal FirstKey { get; set; }

	[Key]
	[Required]
	public int SecondKey { get; set; }
}

The solution was actually in the error message itself but I saw there were alot of people having troubles finding a solution.
You need to create an attribute Column to define the keys.
Here is the code of my model that solved my multiple key problem.

public class ModelObject
{
	[Key]
	[Required]
	[Column(Order=0)]
	public decimal FirstKey { get; set; }

	[Key]
	[Required]
	[Column(Order=1)]
	public int SecondKey{get; set; }
}

Hopefully this saved you alot of time searching for an answer.

Missing aspnet_regiis.exe in C:\Windows\Microsoft.NET\Framework\v4.0.30319

Posted October 9th, 2011

I was having some problems configurating a site in IIS that makes use of aspx pages.
I always got the errormessage “Bad module ManagedPipelineHandler in its module list”.

The problem here was that there was no ASP.NET registered in IIS. You can do this by simply running the command aspnet_regiis.exe -i

That was an easy solution but finding the aspnet_regiis.exe file was something else.
Nowhere in my Framework\v4.0.30319 i could find the file aspnet_regiis.exe

The solution for finding this file is installing the “full” version of the .NET Framework 4.0
The download file can be found here

After downloading and installing the full .NET Framework 4.0 there was a file aspnet_regiis.exe and after running the command everything worked great.

free url sumission