Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Friday, April 11, 2014

How to call for a dynamic OrderBy method for a LINQ?

As I wanted to do some experiences in Asp.Mvc 4 I needed a nice way to generate tables using Ajax calls for showing rows, edit, delete and create new item as well with filtering and paging functions
For that I have found this nice package jTable. You could go to http://www.jtable.org/ where you can see a demo by yourself.

Now that I have introduced the scenario I came to an issue. When implementing the sorting of columns by pressing on a column I had as an input parameter string jtSorting which had as a value: "Name ASC", so column name and ordering. Then in my controller's action I had a LINQ query that accessed also the OrderBy extension method which needs exactly the name of property. So I needed a method to order dynamically by property as a string.

Happily I found a solution. Here are my helper classes that I used in final extension method.

public static class OrderHelper
    {
        public class ColumnToSort
        {
            public string ColumnName { get; set; }
            public SortDirection Direction { get; set; }

            public ColumnToSort()
            { }

            public ColumnToSort(string columnName, SortDirection direction)
            {
                ColumnName = columnName;
                Direction = direction;
            }
        }

        public static ColumnToSort SplitJqueryFormatColumn(string sortingColumn) //assume we have as input: "Name ASC"
        {
            ColumnToSort columnToSort = new ColumnToSort();

            if (sortingColumn != null)
            {
                string[] parts = sortingColumn.Split(' ');
                if (parts.Length == 2)
                {
                    columnToSort.ColumnName = parts[0];
                    columnToSort.Direction = parts[1].ToLower() == "asc" ? SortDirection.Ascending : SortDirection.Descending;
                }
            }

            return columnToSort;
        }
    }

This is the extension method that will Order dynamically by a column string value and an sorting order.

public static class OrderExt
    {
        public static IOrderedQueryable< T > Order< T>(this IQueryable< T> source, string propertyName, SortDirection descending, bool anotherLevel = false)
        {
            var param = Expression.Parameter(typeof(T), string.Empty);
            var property = Expression.PropertyOrField(param, propertyName);
            var sort = Expression.Lambda(property, param);

            var call = Expression.Call(
                typeof(Queryable),
                (!anotherLevel ? "OrderBy" : "ThenBy") +
                (descending == SortDirection.Descending ? "Descending" : string.Empty),
                new[] { typeof(T), property.Type },
                source.Expression,
                Expression.Quote(sort));

            return (IOrderedQueryable< T>)source.Provider.CreateQuery< T>(call);
        }
    }

Here is how to use the Order extension method for List Action that is needed for JTable in ASP.NET MVC 4:

[HttpPost]
        public JsonResult List(int jtStartIndex, int jtPageSize, string jtSorting = null)
        {
            try
            {
                int totalItemsNumber = db.Authors.Count();
        
                OrderHelper.ColumnToSort columnToSort = new OrderHelper.ColumnToSort();
                if (jtSorting != null)
                    columnToSort = OrderHelper.SplitJqueryFormatColumn(jtSorting);
                else
                    columnToSort = new OrderHelper.ColumnToSort("Name", SortDirection.Ascending);

                List< author> authors = db.Authors
                                         .Order(columnToSort.ColumnName, columnToSort.Direction)
                                         .Skip(jtStartIndex)
                                         .Take(jtPageSize)
                                         .ToList();

                return Json(new { Result = "OK", Records = authors, TotalRecordCount = totalItemsNumber });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

Hope it solved your issue, too.

Source for the extension method found at: linq-to-entities-dynamic-sorting.

Monday, January 27, 2014

How to loop through a collection that supports IEnumerable?

Whenever you get to this issue, though it seems a really easy job to do here 2 ways how you can iterate on a collection that supports IEnumerable:

First one using a foreach statement:

foreach (var item in collection)
{
    // play with your item
}

I suggest that always when you know your object types of collection to use that type instead of var. I always try to avoid var type. It is something that my team lead advised me and I came to realize it is a good practice.

Then second way to do it is using for statement. Whenever you have a collection and you need to iterate it and according to some conditions some elements might have to be removed you cannot use foreach because you will have a nice error saying: "Collection was modified; enumeration operation may not execute" :) So that is why you need to use for statement.

for(int i = 0; i < collection.Count(); i++) 
{
    string str1 = collection.ElementAt(i);
    // play with your item
}

There might be other ways to iterate, like using GetEnumerator but is enough, for the moment :)
Have a nice day.

Monday, January 20, 2014

How to make a custom richTextBox control in winforms with C#?

During the last week I had to make a custom control that should have had a richTextBox control with a toolbar that contains: a dropdown of fonts and one with font sizes plus 3 buttons(which in fact are checkboxes with Appearance of a button) that will emulate 'make bold', 'make italic', 'make underline'. Of course there could be other improvements but client was happy with only these controls.


I will try to explain you which are the steps in the next lines:

- create a new control - ExtraRichTextBoxUC
- add 2 comboboxes with drop down style set on DropDownList: cmbFontFamily, cmbFontSize
- add 3 checkBoxes with Appearance on Button: ckbBold, ckbItalic, ckbUnderline
- finally you add a richTextBox control: txtFunctionality

Generate event methods for controls as follows: cmbFontFamily_SelectedIndexChanged, cmbFontSize_SelectedIndexChanged, ckbBold_CheckedChanged, ckbItalic_CheckedChanged, ckbUnderline_CheckedChanged.

I think that one of the most important methods from bellow is ChangeFontStyleForSelectedText. You have to understand that when you want to change font for a text you must iterate character by character and change font. First I thought that a style can be applied a word or a phrase. To issue is that styles are overwritten in such a case so you must iterate each letter.
So for each text that you want to change font you copy in a memory RichTextBox(so you won't cause flickering on current richTextBox) and set new font. Finally that rtf generated you assign to current richTextBox.

private void ChangeFontStyleForSelectedText(string familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle)
        {
            _maskChanges = true;
            try
            {
                int txtStartPosition = txtFunctionality.SelectionStart;
                int selectionLength = txtFunctionality.SelectionLength;
                if (selectionLength > 0)
                    using (RichTextBox txtTemp = new RichTextBox())
                    {
                        txtTemp.Rtf = txtFunctionality.SelectedRtf;
                        for (int i = 0; i < selectionLength; ++i)
                        {
                            txtTemp.Select(i, 1);
                            txtTemp.SelectionFont = RenderFont(txtTemp.SelectionFont, familyName, emSize, fontStyle, enableFontStyle);
                        }

                        txtTemp.Select(0, selectionLength);
                        txtFunctionality.SelectedRtf = txtTemp.SelectedRtf;
                        txtFunctionality.Select(txtStartPosition, selectionLength);
                    }
            }
            finally
            {
                _maskChanges = false;
            }
        }
Next method important that I had to work a little on is RenderFont:
/// 
        /// Changes a font from originalFont appending other properties
        /// 
        /// Original font of text
        /// Target family name
        /// Target text Size
        /// Target font style
        /// true when enable false when disable
        /// A new font with all provided properties added/removed to original font
        private Font RenderFont(Font originalFont, string familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle)
        {
            if (fontStyle.HasValue && fontStyle != FontStyle.Regular && fontStyle != FontStyle.Bold && fontStyle != FontStyle.Italic && fontStyle != FontStyle.Underline)
                throw new System.InvalidProgramException("Invalid style parameter to ChangeFontStyleForSelectedText");

            Font newFont;
            FontStyle? newStyle = null;
            if (fontStyle.HasValue)
            {
                if (fontStyle.HasValue && fontStyle == FontStyle.Regular)
                    newStyle = fontStyle.Value;
                else if (originalFont != null && enableFontStyle.HasValue && enableFontStyle.Value)
                    newStyle = originalFont.Style | fontStyle.Value;
                else
                    newStyle = originalFont.Style & ~fontStyle.Value;
            }

            newFont = new Font(!string.IsNullOrEmpty(familyName) ? familyName : originalFont.FontFamily.Name,
                                emSize.HasValue ? emSize.Value : originalFont.Size,
                                newStyle.HasValue ? newStyle.Value : originalFont.Style);
            return newFont;
        }

Observation: you must highlight the toolbar for your current position. For that after you load the rtf text you must position on first position of your text and according to that font you show font family, font size, if is bold - underline or italic.

In order to catch key combination of Ctrl+B, Ctrl+I, Ctrl+U you will use _KeyDown event of richTextBox control. For Control+I you must use a trick. Setting SuppressKeyPress = true will avoid executing 'Insert TAB' :)

In order to avoid flickering of text in richTextBox control especially when you delete last letter of control or when you try to detect font for first letter of textBox you have to use another trick. Use Suspend/Resume methods of next extension.

namespace System.Windows.Forms
{
    public static class ControlExtensions
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern bool LockWindowUpdate(IntPtr hWndLock);

        //Method used agains flickering
        public static void Suspend(this Control control)
        {
            LockWindowUpdate(control.Handle);
        }

        public static void Resume(this Control control)
        {
            LockWindowUpdate(IntPtr.Zero);
        }
    }
}

I hope that this will help you a lot. When I searched around I did not found such as a control that will make a simple richTextBox with simple toolbar controls. If you encounter issues implementing it feel free to ask. I could also share code but I don't know a good reliable service to share files and not to be removed after a while :-? Do you?

Full code of control:

public partial class ExtraRichTextBoxUC : UserControl
    {
        private bool _maskChanges;
        public ExtraRichTextBoxUC()
        {
            InitializeComponent();
            LoadData();

            DisplayData();
        }

        private void DisplayData()
        {
//dummy data to preview
txtFunctionality.Rtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Tahoma;}{\f1\fnil\fcharset0 Times New Roman;}}\viewkind4\uc1\pard\b\f0\fs18 W\b0 indows 8.1, Windows Server 2012 R2, \b Windows\b0  8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 \fs24 R2 (Server \fs18 Core Role \ul supported with SP1 \ulnone or later; Itanium \fs24 not supported\fs18 ).NET Framework does not support all versions of \fs26 every\f1  platform. For \f0 a list of \fs18 the supported versions, see .NET Framework System Requirements.\par}";

            GoToFirstPositionAndHighlightToolbar();
        }

        private void LoadData()
        {
            LoadRichTextEditorData();
        }

        private void LoadRichTextEditorData()
        {
            string[] availableFontFamilies;

            //check to see if fonts are installed on machine
            try
            {
                availableFontFamilies = new string[] { 
                new FontFamily("Arial").Name, 
                new FontFamily("Microsoft Sans Serif").Name, 
                new FontFamily("Tahoma").Name, 
                new FontFamily("Times New Roman").Name 
                };
            }
            catch (ArgumentException e)
            {
                throw new Exception("Font not present: " + e.Message);
            }

            List < object > availableFontSizes = new List < object >();

            for (float i = 8; i <= 14; i++)
                availableFontSizes.Add(i);

            cmbFontFamily.Items.AddRange(availableFontFamilies);
            cmbFontSize.Items.AddRange(availableFontSizes.ToArray());
        }

        private void ckbBold_CheckedChanged(object sender, EventArgs e)
        {
            if (_maskChanges)
                return;

            ChangeOrSetFont(string.Empty, null, FontStyle.Bold, ckbBold.Checked);
            txtFunctionality.Focus();
        }

        private void ckbItalic_CheckedChanged(object sender, EventArgs e)
        {
            if (_maskChanges)
                return;

            ChangeOrSetFont(string.Empty, null, FontStyle.Italic, ckbItalic.Checked);
            txtFunctionality.Focus();
        }

        private void ckbUnderline_CheckedChanged(object sender, EventArgs e)
        {
            if (_maskChanges)
                return;

            ChangeOrSetFont(string.Empty, null, FontStyle.Underline, ckbUnderline.Checked);
            txtFunctionality.Focus();
        }

        private void cmbFontFamily_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_maskChanges)
                return;

            ChangeOrSetFont(cmbFontFamily.SelectedItem.ToString(), null, null, null);
            txtFunctionality.Focus();
        }

        private void cmbFontSize_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_maskChanges)
                return;
            ChangeOrSetFont(null, float.Parse(cmbFontSize.SelectedItem.ToString()), null, null);
            txtFunctionality.Focus();
        }

        private void ChangeOrSetFont(string familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle)
        {
            if (txtFunctionality.SelectionType == RichTextBoxSelectionTypes.Empty)
            {
                SetSelectionFont(familyName, emSize, fontStyle, enableFontStyle);
            }
            else
            {
                ChangeFontStyleForSelectedText(familyName, emSize, fontStyle, enableFontStyle);
            }
        }

        private void SetSelectionFont(string familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle)
        {
            Font renderedFont = RenderFont(txtFunctionality.SelectionFont, familyName, emSize, fontStyle, enableFontStyle);
            txtFunctionality.SelectionFont = renderedFont;
        }

        private void ChangeFontStyleForSelectedText(string familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle)
        {
            _maskChanges = true;
            try
            {
                int txtStartPosition = txtFunctionality.SelectionStart;
                int selectionLength = txtFunctionality.SelectionLength;
                if (selectionLength > 0)
                    using (RichTextBox txtTemp = new RichTextBox())
                    {
                        txtTemp.Rtf = txtFunctionality.SelectedRtf;
                        for (int i = 0; i < selectionLength; ++i)
                        {
                            txtTemp.Select(i, 1);
                            txtTemp.SelectionFont = RenderFont(txtTemp.SelectionFont, familyName, emSize, fontStyle, enableFontStyle);
                        }

                        txtTemp.Select(0, selectionLength);
                        txtFunctionality.SelectedRtf = txtTemp.SelectedRtf;
                        txtFunctionality.Select(txtStartPosition, selectionLength);
                    }
            }
            finally
            {
                _maskChanges = false;
            }
        }

        /// 
        /// Changes a font from originalFont appending other properties
        /// 
        /// Original font of text
        /// Target family name
        /// Target text Size
        /// Target font style
        /// true when enable false when disable
        /// A new font with all provided properties added/removed to original font
        private Font RenderFont(Font originalFont, string familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle)
        {
            if (fontStyle.HasValue && fontStyle != FontStyle.Regular && fontStyle != FontStyle.Bold && fontStyle != FontStyle.Italic && fontStyle != FontStyle.Underline)
                throw new System.InvalidProgramException("Invalid style parameter to ChangeFontStyleForSelectedText");

            Font newFont;
            FontStyle? newStyle = null;
            if (fontStyle.HasValue)
            {
                if (fontStyle.HasValue && fontStyle == FontStyle.Regular)
                    newStyle = fontStyle.Value;
                else if (originalFont != null && enableFontStyle.HasValue && enableFontStyle.Value)
                    newStyle = originalFont.Style | fontStyle.Value;
                else
                    newStyle = originalFont.Style & ~fontStyle.Value;
            }

            newFont = new Font(!string.IsNullOrEmpty(familyName) ? familyName : originalFont.FontFamily.Name,
                                emSize.HasValue ? emSize.Value : originalFont.Size,
                                newStyle.HasValue ? newStyle.Value : originalFont.Style);
            return newFont;
        }

        private void txtFunctionality_SelectionChanged(object sender, EventArgs e)
        {
            if (_maskChanges)
                return;

            if (string.IsNullOrEmpty(txtFunctionality.Text))
            {
                //clear all text with its ex-formatting
                txtFunctionality.Clear();
                LoadAndSetDefaultFont();
            }
            else
            {
                ScanSelectedTextAndHighlightToolbar();
            }
        }

        private void txtFunctionality_KeyDown(object sender, KeyEventArgs e)
        {
            if (_maskChanges)
                return;

            if (e.Control && e.KeyCode == Keys.B)
            {
                ckbBold.Checked = !ckbBold.Checked;
                e.Handled = true;
            }
            else if (e.Control && e.KeyCode == Keys.I)
            {
                ckbItalic.Checked = !ckbItalic.Checked;
                e.Handled = true;
                e.SuppressKeyPress = true; //avoid executing 'Insert TAB' for CTRL + I
            }
            else if (e.Control && e.KeyCode == Keys.U)
            {
                ckbUnderline.Checked = !ckbUnderline.Checked;
                e.Handled = true;
            }
        }

        private void GoToFirstPositionAndHighlightToolbar()
        {
            _maskChanges = true;
            try
            {
                if (!string.IsNullOrEmpty(txtFunctionality.Text))
                {
                    txtFunctionality.Suspend();
                    txtFunctionality.Select(0, 1);

                    using (RichTextBox txtTemp = new RichTextBox())
                    {
                        txtTemp.Rtf = txtFunctionality.SelectedRtf;
                        Font currFont = txtTemp.SelectionFont;

                        HighlightToolbar(currFont.FontFamily.Name, currFont.Size, currFont.Bold, currFont.Italic, currFont.Underline);
                    }
                    txtFunctionality.Select(0, 0);
                    txtFunctionality.Resume();
                }
                else
                {
                    LoadAndSetDefaultFont();
                }
            }
            finally
            {
                _maskChanges = false;
            }
        }
        
        private Font GetFontFromToolbar()
        {
            FontStyle toolbarFontStyle = new FontStyle();
            if (ckbBold.Checked)
                toolbarFontStyle |= FontStyle.Bold;
            if (ckbItalic.Checked)
                toolbarFontStyle |= FontStyle.Italic;
            if (ckbUnderline.Checked)
                toolbarFontStyle |= FontStyle.Underline;

            Font font = new Font(cmbFontFamily.SelectedItem.ToString(), (float)cmbFontSize.SelectedItem, toolbarFontStyle);
            return font;
        }

        //could be changed into an extentension 
        public string TrimLastChar(string text)
        {
            if (text.Length >= 1)
                return text.Substring(0, text.Length - 1);
            else
                return text;
        }

        private void LoadAndSetDefaultFont()
        {
            Font font = txtFunctionality.Font;
            HighlightToolbar(font.FontFamily.Name, font.Size, font.Bold, font.Italic, font.Underline);

            SetSelectionFont(font.FontFamily.Name, font.Size, font.Style, null);
        }

        private void ScanSelectedTextAndHighlightToolbar()
        {
            _maskChanges = true;
            try
            {
                if (txtFunctionality.SelectionType == RichTextBoxSelectionTypes.Empty)
                {
                    int selectionStart = txtFunctionality.SelectionStart != 0 ? txtFunctionality.SelectionStart - 1 : 0;
                    int selectionEnd = txtFunctionality.SelectionStart;

                    txtFunctionality.Suspend();
                    //case when passes to a new line - it looses font style so must get from Tooolbar
                    if (TrimLastChar(txtTextContent.Text).EndsWith("\n"))
                    {
                        txtTextContent.Select(selectionStart, 1);
                        txtTextContent.SelectionFont = GetFontFromToolbar();
                        txtTextContent.Select(selectionEnd, 0);
                    }
                    else
                    {
                        txtTextContent.Select(selectionStart, 1);
                        using (RichTextBox txtTemp = new RichTextBox())
                        {
                            txtTemp.Rtf = txtTextContent.SelectedRtf;
                            Font currFont = txtTemp.SelectionFont;

                            HighlightToolbar(currFont.FontFamily.Name, (float)Math.Truncate(currFont.Size), currFont.Bold, currFont.Italic, currFont.Underline);
                            txtTextContent.SelectionFont = currFont;
                        }
                        txtTextContent.Select(selectionEnd, 0);
                    }
                    txtFunctionality.Resume();
                }
                else
                    if (!string.IsNullOrEmpty(txtFunctionality.SelectedText))
                    {
                        int txtStartPosition = txtFunctionality.SelectionStart;
                        int selectionLength = txtFunctionality.SelectionLength;

                        if (selectionLength > 0)
                            using (RichTextBox txtTemp = new RichTextBox())
                            {
                                txtTemp.Rtf = txtFunctionality.SelectedRtf;

                                if (selectionLength < 2)
                                {
                                    FontFamily firstCharFontFamily = txtTemp.SelectionFont.FontFamily;
                                    float firstCharSize = txtTemp.SelectionFont.Size;
                                    bool isBold = txtTemp.SelectionFont.Bold;
                                    bool isItalic = txtTemp.SelectionFont.Italic;
                                    bool isUnderline = txtTemp.SelectionFont.Underline;

                                    HighlightToolbar(firstCharFontFamily.Name, firstCharSize, isBold, isItalic, isUnderline);
                                }
                                else
                                {
                                    txtTemp.Select(0, 1);
                                    FontFamily firstCharFontFamily = txtTemp.SelectionFont.FontFamily;
                                    float firstCharSize = txtTemp.SelectionFont.Size;
                                    bool isBold = txtTemp.SelectionFont.Bold;
                                    bool isItalic = txtTemp.SelectionFont.Italic;
                                    bool isUnderline = txtTemp.SelectionFont.Underline;

                                    bool sameFontFamily = true, sameFontSize = true;

                                    for (int i = 1; i < selectionLength; i++)
                                    {
                                        txtTemp.Select(i, 1);
                                        sameFontFamily = txtTemp.SelectionFont.FontFamily.Name == firstCharFontFamily.Name;
                                        sameFontSize = txtTemp.SelectionFont.Size == firstCharSize;
                                        isBold = isBold && txtTemp.SelectionFont.Bold;
                                        isItalic = isItalic && txtTemp.SelectionFont.Italic;
                                        isUnderline = isUnderline && txtTemp.SelectionFont.Underline;

                                        if (!sameFontFamily && !sameFontSize && !isBold && !isItalic && !isUnderline)
                                            break;
                                    }

                                    HighlightToolbar(sameFontFamily ? firstCharFontFamily.Name : string.Empty,
                                        sameFontSize ? firstCharSize : (float?)null,
                                        isBold, isItalic, isUnderline);
                                }
                            }
                    }
            }
            finally
            {
                _maskChanges = false;
            }
        }

        private void HighlightToolbar(string commonFamilyName, float? emSize, bool? isBold, bool? isItalic, bool? isUnderline)
        {
            if (!string.IsNullOrEmpty(commonFamilyName))
                cmbFontFamily.SelectedItem = commonFamilyName;
            else
                cmbFontFamily.SelectedItem = null;

            if (emSize.HasValue)
                cmbFontSize.SelectedItem = (float)Math.Truncate(emSize.Value);
            else
                cmbFontSize.SelectedItem = null;

            if (isBold.HasValue)
            {
                ckbBold.CheckState = isBold.Value ? CheckState.Checked : CheckState.Unchecked;
            }
            else
                ckbBold.CheckState = CheckState.Unchecked;

            if (isItalic.HasValue)
            {
                ckbItalic.CheckState = isItalic.Value ? CheckState.Checked : CheckState.Unchecked;
            }
            else
                ckbItalic.CheckState = CheckState.Unchecked;

            if (isUnderline.HasValue)
            {
                ckbUnderline.CheckState = isUnderline.Value ? CheckState.Checked : CheckState.Unchecked;
            }
            else
                ckbUnderline.CheckState = CheckState.Unchecked;
        }
    }
}

namespace System.Windows.Forms
{
    public static class ControlExtensions
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern bool LockWindowUpdate(IntPtr hWndLock);

        //Method used agains flickering
        public static void Suspend(this Control control)
        {
            LockWindowUpdate(control.Handle);
        }

        public static void Resume(this Control control)
        {
            LockWindowUpdate(IntPtr.Zero);
        }
    }

Monday, September 16, 2013

How to calculate the next business days in C#?

There are cases when according to a business day(Monday to Friday) and number of days you have to return the computed business day. Of course the result can not be on week-end.
So if you ever encounter this scenario when you have a certain date and you want to add x days to it and then return the dateTime found you could use the next extension.
I admit that this extension is a very basic solution. I refer to the fact that I don't take into consideration holidays. If you want a more complex solution then you could go to Dynamic-Holiday-Date-Calculator. Or you could create a list of holidays and then make another method - IsHoliday() that should check if a certain date is part of your holiday calendar.

The idea of this algorithm is simple. In a while block we add one day to our original date time and as long as the result date is not in weekend we decrease number of bussiness days to add.
 
        ///
        /// Adds business days to a date
        /// 
        /// 
        /// 
        /// 
        public static DateTime AddBusinessDays(this DateTime dateTime, int businessDays)
        {
            DateTime resultDate = dateTime;
            while (businessDays > 0)
            {
                resultDate = resultDate.AddDays(1);
                if (resultDate.DayOfWeek != DayOfWeek.Saturday &&
                    resultDate.DayOfWeek != DayOfWeek.Sunday)
                    businessDays--;
            }
            return resultDate;
        }

Hope that helped you ;)

Thursday, March 14, 2013

How to design Windows Forms with Abstract Inheritance?

It happened few days ago when I got to this nice error:

The designer must create an instance of type '... .BaseClass.TabBaseControl' but it cannot because the type is declared as abstract.


The scenario was like this: I had a Base class where a defined abstract members that where implemented in a form. When wanted to see the design of the page this warning appeared even though the application runs just fine. So how to get rid of this error:  "The designer must create an instance of type 'SchedeMaterialiDaTaglio.BaseClass.TabBaseControl' but it cannot because the type is declared as abstract. " ?
Well, searching around I got to this post http://www.platinumbay.com/blogs/dotneticated/archive/2008/01/05/designing-windows-forms-with-abstract-inheritance.aspx where I found part of the solution. 
Here it is:

 public class AbstractCommunicatorProvider : TypeDescriptionProvider
    {
        public AbstractCommunicatorProvider()
            : base(TypeDescriptor.GetProvider(typeof(UserControl)))
        {
        }
        public override Type GetReflectionType(Type objectType, object instance)
        {
            return typeof(UserControl);
        }
        public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
        {
            objectType = typeof(UserControl);
            return base.CreateInstance(provider, objectType, argTypes, args);
        }
    }
You define this class in inherited class(it only worked for me in this way) and you must also put this for base class and inherited class:

    [TypeDescriptionProvider(typeof(AbstractCommunicatorProvider))]
    public partial class TabUC : TabBaseControl{}

    [TypeDescriptionProvider(typeof(AbstractCommunicatorProvider))]
    public abstract class TabBaseControl : UserControl, ITabBase{}
Of course that you will have to include System.ComponentModel namespace and others just as needed.
Hope it helped. Ciao.

Friday, March 8, 2013

How to solve "Object reference not set to an instance of an object" in Design Time, Visual Studio, Winforms?

If you ever encounter this nice message then here is what you should do in order to fix "Object reference not set to an instance of an object" showing in Design Time even if code runs just fine.

I will tell you how I encountered it. I created a user control that has a property. In a page form I included this user control among others. In control's Load event I had to use that defined property. And I did not understood why it needs to know the value in design time, however it shows this nice error. It is obvious that is not set. It is only set when running.
So. Ready with long talk. The only think you need to get away of this "Object reference not set to an instance of an object" error you must use DesignMode property of the control. :)

if (!this.DesignMode)
{
   //your code here that generates the error
}
Well, hope that I helped you today with this error. Keep up the good code ;)

Friday, January 25, 2013

How to maintain the current scroll position across postbacks in Asp.Net?

It might sometimes happen that when you submit a page you want that the scroll position of the page remain the same. So how do you do that, in Asp.Net?

First I thought about some javascript code. Well you don't need some extra js functions when Asp.Net has a built in property.

Well, in order to keep scroll position of the page the same after submit you have to set in page declaration MaintainScrollPositionOnPostback  property to "true".

As I said in order to maintain the current scroll position across postbacks you can do this:
<%@ Page MaintainScrollPositionOnPostback="true" %>

Regards.

Friday, December 14, 2012

How to check CheckedListBox item with single click in Windows Forms Application?

If you want that when you check an item in CheckedListBox control in Windows Forms Application the item to be checked from first click there is a trick you need to do it.
As I developed more with Asp.Net, web applications, it was very awkward for me that when I checked the item in checkedListBox control it did not checked it but rather kind of selected it.
Well, in order to answer your question you have to make only one modification: select the control and then press Alt + Enter for Properties and then look for CheckOnClick property. Set it on True.

There you go :)
If this post helped you, leave a comment or share it :)

Thursday, October 4, 2012

How to get country, city, language for an ip address, in Asp.Net?

When you want to get location information about a client that visits your website according to its ip address you can use a third party service that offers this info in real time or you can use free services, which might not work 100% accurate. However, no matter which service you shall choose you can use the same workflow as I used in my project example.

I created a class that will be used to deserialize json response from api service from easyjquery.com:
 private struct GeoIPResponse
    {
//this is the response I get
        //{"IP":"127.0.0.1","continentCode":"Unknown","continentName":"Unknown",
        //"countryCode2":"Unknown","COUNTRY":"Unknown","countryCode3":"Unknown","countryName":"Unknown","regionName":"Unknown",
        //"cityName":"Unknown","cityLatitude":0,"cityLongitude":0,"countryLatitude":0,"countryLongitude":0,"localTimeZone":"Unknown",
        //"localTime":"0"}
        public string IP;
        public string continentCode;
        public string continentName;
        public string countryCode2;
        public string COUNTRY;
        public string countryCode3;
        public string countryName;
        public string regionName;
        public string cityName;
        public string cityLatitude;
        public string cityLongitude;
        public string countryLatitude;
        public string countryLongitude;
        public string localTimeZone;
        public string localTime;
    }
/*
then I defined some needful methods: 
*/

/// 
    /// Returns Client Ip Address
    /// 
    static public string ClientIpAddress
    {
        get
        {
            string _clientIPAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (!string.IsNullOrEmpty(_clientIPAddress))
            {
                string[] ipRange = _clientIPAddress.Split(',');
                _clientIPAddress = ipRange[ipRange.Length - 1];
            }
            else
            {
                _clientIPAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }

            return _clientIPAddress;
        }

    }

    public string _WebRequest(string strURL)
    {
        String strResult;
        WebResponse objResponse;
        WebRequest objRequest = HttpWebRequest.Create(strURL);
        objRequest.Method = "GET";

        objResponse = objRequest.GetResponse();
        using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
        {
            strResult = sr.ReadToEnd();
            sr.Close();
        }
        return strResult;

    }
and finally this is the way I used a service from www.easyjquery.com: :
protected void Page_Load(object sender, EventArgs e)
{
        txtMessage.Text = "";
        string Result = _WebRequest("http://api.easyjquery.com/ips/?ip=" + ClientIpAddress + "&full=true");

        txtMessage.Text = Result;
        
        JavaScriptSerializer jss = new JavaScriptSerializer();
        var clientGeoLocation = jss.Deserialize < GeoIPResponse >(Result);

        lblMessage.Text = "
Your short details: " + "Country: " + clientGeoLocation.COUNTRY + ", CountryCode 2: " + clientGeoLocation.countryCode2 + ", CountryCode 3: " + clientGeoLocation.countryCode3 +
            ", TimeZone: " + clientGeoLocation.localTimeZone;
}

Wednesday, October 3, 2012

How do you test if a string is null or empty?

Today as I was studying something related to Asp.Net I got to an example where I had to test if a string variable is null or just an empty string. So, which are the possibilities and which is the most efficient?

  • if(myString == String.Empty)
  • if(myString == "")
  • if(myString.Length == 0) - this could throw an exception if myString is null
  • I also found this comparison: if( String.Equals(myString, String.Empty) )
  • and of course method IsNullOrEmpty introduced in .Net Framework 2:
    if(string.IsNullOrEmpty(myString)) which is said to be the most efficient.
Now, which methods do you use when comes to test if a string has a value or not? You are invited to write them as comments :) Of course that no matter which one of the methods above you choose won't slow down to much the performance of your application, but is good to build a good practice for future projects, isn't it?

Tuesday, September 18, 2012

How to format a number to x decimal places in C#?

If you have a decimal, double or int data type number and you want to show the number with a certain decimal places then you can use ToString() method from System namespace.
Have a look at these examples. I hope you will find what you need.

Tuesday, May 15, 2012

How to convert string to string[] in C#?

It might happen that you receive from POST a variable name that is in fact an array. So in this case you should convert your object into string[]. How do you do that?
Well, as usually, it is simple:
string[] RoomOptions = new string[] { Request["room_options"] };
So there you are.
This was for solving asp error message saying:
Error message: Cannot convert type 'string' to 'string[]'

Thursday, April 12, 2012

How to use conditional operator(?:) in c# in a string?

The conditional operator (?:) returns one of two values depending on the value of a Boolean expression.

The condition must evaluate to true or false. If condition is truefirst_expression is evaluated and becomes the result. If condition is falsesecond_expression is evaluated and becomes the result. Only one of the two expressions is evaluated.
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.
This is what MSDN says. :)
Now: it might help you to know how to use conditional operator when generate a string. I will give you a simple method which receives a input parameter and according to that will generate a link.


public string GenerateLink(string Option)
    {
        string Response = "";
       Response = "<a href=\"YourPage.aspx?option=" + ((Option == "holiday") ? "goHoliday" : "goAndWork").ToString() + "\">Click</a>";
        return Response;
    }

So, don't hesitate to use conditional operator whenever you are in need of it.
Have a nice day.

Friday, March 2, 2012

How to validate if an email address is syntax valid in C#?

As a simple question: how do you validate if an email address is correct? (by syntax point of view)
If you need this function, to validate an email address you should use this method which is using regular experssions:
public bool IsEmailSyntaxValid(string emailToValidate)
        {
            return System.Text.RegularExpressions.Regex.IsMatch(emailToValidate,
                @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }

Monday, January 30, 2012

How to iterate through a DataTable in C#?

It often happens when you have a datatable in c# but you don't know how many columns has and its names. So, please take a look at this simple example to loop over a datatable rows. If you have any question don't hesitate in comments section.
DataTable dtCompanies = GetCompanies();
        string Message = "";
        int rowCount = 0;
        foreach (DataRow dRow in dtCompanies.Rows)
        {
            Message += "Row:" + rowCount + ", Columns: ";

            foreach (DataColumn dCol in dtCompanies.Columns)
            {
                Message += dCol.ColumnName + "( " + dtCompanies.Rows[rowCount][dCol].ToString() + " ) ";
            }
            rowCount++;
        }

Saturday, January 21, 2012

How to shut down an application in Asp.Net?

Often when you are updating your website you would not be able to overwrite files, operate in database. That is why you can do the following. Create a file called app_offline.html. In this file you can insert content to show as long time as your application is down for maintenance. You can look here form my application offline page:



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Application Offline</title>
    <style>
        p
        {
            background-color: #ffffcc;
            padding-top: 10px;
            padding-bottom: 10px;
            padding-left: 10px;
            padding-right: 10px;
            border-style: solid;
            border-color: Black;
            border-width: 1px;
        }
    </style>
</head>
<body>
    <h1 class="error">
        Website is updating
    </h1>
    <p style="font-size: 15px;">
        This site is currently updating. Please wait for a while.
        <br />
        Thanks.
    </p>
</body>
</html>



The way app_offline.htm works is that you place this file in the root of your application. When ASP.NET sees it, it will shut-down the app-domain for the application (and not restart it for requests) and instead send back the contents of the app_offline.htm file in response to all new dynamic requests for the application. When you are done updating the site, just delete the file and it will come back online or rename to _app_offline(for example) and you will have the file there for use next time you need it.

Also have in mind that by adding the app_offline.htm the application sends the Application_End and after this function return the rest of the threads of the program are killed. The maximum time of wait for theApplication_End to return is set on the pool settings.

If you stop the full pool then all the sites that under this pool follow the same procedure. If you only open the app_offline.htm then only this site is affected.

To avoid your threads to kill by this shutdown, set a wait state on the Application_End
void Application_End(object sender, EventArgs e) 
{
    // This is a custom function that you must make and
    //   check your threads in the program
    MyTheadClass.WaitForAllMyThreadsToExist();

    // after this function exit the rest of the threads are killed.
}

If you use the app_offline.htm feature, you should make sure you have at least 512 bytes of content within it to make sure that your HTML (instead of IE's friendly status message) shows up to your users.  If you don't want to have a lot of text show-up on the page, one trick you can use is to just add an html client-side comment with some extra content to push it over 512 bytes. You can insert html comments just to make your file bigger.

Monday, January 9, 2012

How to substract 2 ArrayLists in C#?

Well the answer might be really easy for some of you but for newbies is not.
So considering that we have 2 arraylists.
 
ArrayList FirstArray = new ArrayList(new[] { "23", "25", "27" });
ArrayList SecondArray = new ArrayList(new[] { "25", "28", "29" });


and we want the difference.For that this is what you have to do. Call a method that I implemented.
 
ArrayList Difference = Substract2ArrayLists(FirstArray, SecondArray, true);
Method:
 
    /// 
    /// Substracts 2 array lists/a difference
    /// 
    /// 

First ArrayList
    /// 

Second ArrayList
    /// 

True if compare string, False for long values
    /// 
    static public ArrayList Substract2ArrayLists(ArrayList First, ArrayList Second, bool IsString)
    {
        if (IsString)
        {
            foreach (string secondValue in Second)
            {
                First.Remove(secondValue);
            }
        }
        else
        {
            foreach (long secondValue in Second)
            {
                First.Remove(secondValue);
            }
        }
        return First;
    }