Blog Home  Home Feed your aggregator (RSS 2.0)  
kevin Mocha - Monday, June 02, 2008
Bookmarks collected from web.
 
 Monday, June 02, 2008

http://geekswithblogs.net/thibbard/archive/2008/05/20/wpf---collectionviewsource-that-updates-automatically.aspx

public class AutoRefreshCollectionViewSource : CollectionViewSource
{
    protected override void OnSourceChanged(object oldSource, object newSource)
    {
        if (oldSource != null)
        {
            SubscribeSourceEvents(oldSource, true);
        }

        if (newSource != null)
        {
            SubscribeSourceEvents(newSource, false);
        }

        base.OnSourceChanged(oldSource, newSource);
    }


    private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        bool refresh = false;
        foreach (SortDescription sort in SortDescriptions)
        {
            if (sort.PropertyName == e.PropertyName)
            {
                refresh = true;
                break;
            }
        }

        if (!refresh)
        {
            foreach (GroupDescription group in GroupDescriptions)
            {
                PropertyGroupDescription propertyGroup = group as PropertyGroupDescription;

                if (propertyGroup != null && propertyGroup.PropertyName == e.PropertyName)
                {
                    refresh = true;
                    break;
                }
            }
        }

        if (refresh)
        {
            View.Refresh();
        }
    }

    private void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            SubscribeItemsEvents(e.NewItems, false);
        }

        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            SubscribeItemsEvents(e.OldItems, true);
        }
        else
        {
            // TODO: Support this
            Debug.Assert(false);
        }
    }

     
    private void SubscribeItemEvents(object item, bool remove)
    {
        INotifyPropertyChanged notify = item as INotifyPropertyChanged;     

        if (notify != null)
        {
            if (remove)
            {
                notify.PropertyChanged -= Item_PropertyChanged;
            }
            else
            {
                notify.PropertyChanged += Item_PropertyChanged;
            }
        }
    }
     
    private void SubscribeItemsEvents(IEnumerable items, bool remove)
    {
        foreach (object item in items)
        {
            SubscribeItemEvents(item, remove);
        }
    }

    private void SubscribeSourceEvents(object source, bool remove)
    {
        INotifyCollectionChanged notify = source as INotifyCollectionChanged;

        if (notify != null)
        {
            if (remove)
            {
                notify.CollectionChanged -= Source_CollectionChanged;
            }

            else
            {
                notify.CollectionChanged += Source_CollectionChanged;
            }
        }

         
        SubscribeItemsEvents((IEnumerable)source, remove);

    }

}

Using the CollectionViewSource is a good way of binding to a datasource and letting the XAML determine the sorting and grouping of the data. However, as your datasource changes, the grouping and sorting is not automatically "re-calculated", forcing your code to be smarter that it should be. I found a class today on MSDN forums that inherits from CollectionViewSource and adds automatic refresh capabilities. This code is smart enough to resort your items, regroup your items and even add new groupings as needed.
Some good CollectionViewSource links:

Monday, June 02, 2008 7:49:01 PM UTC  #    Comments [0]    |  Trackback
 Thursday, May 29, 2008
 Tuesday, May 27, 2008

http://channel9.msdn.com/wiki/default.aspx/SecurityWiki.RegExInputValCode

 // Decomposed method which actually creates the pattern object and determines the match.
        // Used by all of the other functions. 
        static bool MatchString(string str, string regexstr)
        {
                    str = str.Trim();
                    System.Text.RegularExpressions.Regex pattern = new System.Text.RegularExpressions.Regex(regexstr);
 
 
                    return pattern.IsMatch(str);
        }
 
 
        static bool IsValidUserName(string strUsername)
        {
                    // Allows word characters [A-Za-z0-9_], single quote, dash and period
                    // must be at least two characters long and less then 128
                    string regExPattern = @"^[\w-'\.]{2,128}$";
 
 
                    // We also permit email address characters in user name. Set to false
                    // if you don't permit email addresses as usernames. 
                    bool allowEmailUsernames = true;
 
 
                    if (allowEmailUsernames)
                    {
                        return (MatchString(strUsername, regExPattern) || IsValidEmailAddress(strUsername));
                    }
                    else
                    {
                                return MatchString(strUsername, regExPattern);
                    }
        }
 
 
        static bool IsValidPassword(string strPassword)
        {
                    // Allows any type of character
 
 
                    // If complexity is enabled, the password must be longer
                    // and contain at least one uppercase, one lowercase, 
                    // one numeric and one symbolic character. Set to false 
                    // if your requirements differ.
                    bool passwordComplexity = true;
 
 
                    // These are some proposed minimum password lengths. If
                    // complexity is enabled (above), the stronger (longer) 
                    // minimum password rule applies. 
                    int minPasswordLen = 6;
                    int strongPasswordLen = 8;
 
 
                    if(passwordComplexity) {
                        string regExPattern = @"^.*(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[`~!@#\$%\^\&\*\(\)-_\=\+\[\{\]\}\\\|;:',<\.>/?]).*$";  
                        return(strPassword.Length >= strongPasswordLen &&
                            MatchString(strPassword, regExPattern));
                    } else {
                                return(strPassword.Length >= minPasswordLen);
                    }
        }
 
 
        static bool IsValidName(string strName)
        {
                    // Allows alphabetical chars, single quote, dash and space
                    // must be at least two characters long and caps out at 128 (database size)
                    string regExPattern = @"^[a-zA-Z-'\.\s]{2,128}$";  
                    return MatchString(strName, regExPattern);
        }
 
 
        static bool IsValidStreetAddress(string strAddress)
        {
                    // Since so many different types of address formats we're just going to swing the bat at 
                    // this one for now and do a match against a series of digits (potentially containing
                    // punctuation), followed by a series of characters representing the street name and then
                    // potentially a type of street and unit number
                    string regExPattern = @"\d{1,3}.?\d{0,3}\s[a-zA-Z]{2,30}(\s[a-zA-Z]{2,15})?([#\.0-9a-zA-Z]*)?";
                    return MatchString(strAddress, regExPattern);
        }
 
 
        static bool IsValidCity(string strCity)
        {
                    // Here we simply treat city names like people names and defer to our name validation function. 
                    return IsValidName(strCity);
        }
 
 
        static bool IsValidUSState(string strState)
        {
                    // Names of 50 US States
                    string[] stateNames=         {"ALABAMA","ALASKA","ARIZONA","ARKANSAS","CALIFORNIA","COLORADO","CONNECTICUT","DELAWARE","FLORIDA","GEORGIA","HAWAII","IDAHO","ILLINOIS","INDIANA","IOWA","KANSAS","KENTUCKY","LOUISIANA","MAINE","MARYLAND","MASSACHUSETTS","MICHIGAN","MINNESOTA","MISSISSIPPI","MISSOURI","MONTANA","NEBRASKA","NEVADA","NEW HAMPSHIRE","NEW JERSEY","NEW MEXICO","NEW YORK","NORTH CAROLINA","NORTH DAKOTA","OHIO","OKLAHOMA","OREGON","PENNSYLVANIA","RHODE ISLAND","SOUTH CAROLINA","SOUTHDAKOTA","TENNESSEE","TEXAS","UTAH","VERMONT","VIRGINIA","WASHINGTON","WEST VIRGINIA","WISCONSIN","WYOMING"};
            // Postal codes of 50 US States
            string[] stateCodes =         {"AL","AK","AZ","AR","CA","CO","CT","DE","DC","FL","GA","HI","ID","IL","IN","IA","KS","KY","LA","ME","MD","MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ","NM","NY","NC","ND","OH","OK","OR","PA","RI","SC","SD","TN","TX","UT","VT","VA","WA","WV","WI","WY"};
 
 
 
 
            // This one is somewhat easier because we have a finite set of values to check against.
            // We simply uppercase our value anc check against our list.
            strState = strState.ToUpper();
 
 
            ArrayList stateCodesArray = new ArrayList(stateCodes);
            ArrayList stateNamesArray = new ArrayList(stateNames);
 
 
            return (stateCodesArray.Contains(strState) || stateNamesArray.Contains(strState));
        }
 
 
        static bool IsValidZIPCode(string strZIP)
        {
                    // Allows 5 digit, 5+4 digit and 9 digit zip codes
                    // must be at least two characters long and caps out at 128 (database size)
                    string regExPattern = @"^(\d{5}-\d{4}|\d{5}|\d{9})$";  
                    return MatchString(strZIP, regExPattern);
        }
 
 
        static bool IsValidUSPhoneNumber(string strPhone)
        {
                    // Allows phone number of the format: NPA = [2-9][0-8][0-9] Nxx = [2-9][0-9][0-9] Station = [0-9][0-9][0-9][0-9]
                    string regExPattern = @"^[01]?[- .]?(\([2-9]\d{2}\)|[2-9]\d{2})[- .]?\d{3}[- .]?\d{4}$";  
                    return MatchString(strPhone, regExPattern);
        }
 
 
        static bool IsValidCCNumber(string strCCNumber)
        {
                    // This expression is basically looking for series of numbers confirming to the standards
                    // for Visa, MC, Discover and American Express with optional dashes between groups of numbers
                    string regExPattern = @"^((4\d{3})|(5[1-5]\d{2})|(6011))-?\d{4}-?\d{4}-?\d{4}|3[4,7][\d\s-]{15}$";
                    return MatchString(strCCNumber, regExPattern);
        }
 
        static bool IsValidSSN(string strSSN)
        {
                    // Allows SSN's of the format 123-456-7890. Accepts hyphen delimited SSN’s or plain numeric values.
                    string regExPattern = @"^\d{3}[-]?\d{2}[-]?\d{4}$";
                    return MatchString(strSSN, regExPattern);
        }
 
 
        static bool IsValidEmailAddress(string strEmail) 
        {
                    // Allows common email address that can start with a alphanumeric char and contain word, dash and period characters
                    // followed by a domain name meeting the same criteria followed by a alpha suffix between 2 and 9 character lone
                    string regExPattern = @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$";  
                    return MatchString(strEmail, regExPattern);
        }
 
 
        static bool IsValidURL(string strURL)
        {
                    // Allows HTTP and FTP URL's, domain name must start with alphanumeric and can contain a port number
                    // followed by a path containing a standard path character and ending in common file suffixies found in URL's
                    // and accounting for potential CGI GET data
                    string regExPattern = @"^^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_=]*)?$";  
                    return MatchString(strURL, regExPattern);
        }
 
 
        static bool IsValidIPAddress(string strIP)
        {
                    // Allows four octets of numbers that contain values between 4 numbers in the IP address to 0-255 and are separated by periods
                    string regExPattern = @"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
                    return MatchString(strIP, regExPattern);
        }
 
 
        static bool IsValidAlphaText(string strAlpha)
        {
                    // Allows one or more alphabetical characters. This is a more generic validation function.
                    string regExPattern = @"^[A-Za-z]+$";
                    return MatchString(strAlpha, regExPattern);
        }
 
 
        static bool IsValidAlphaNumericText(string strAlphaNum)
        {
                    // Allows one or more alphabetical and/or numeric characters. This is a more generic validation function.
                    string regExPattern = @"^[A-Za-z0-9]+$";
                    return MatchString(strAlphaNum, regExPattern);
        }
 
 
        static bool IsValidNumericText(string strNumeric)
        {
                    // Allows one or more positive or negative, integer or decimal numbers. This is a more generic validation function.
                    string regExPattern = @"/[+-]?\d+(\.\d+)?$";
                    return MatchString(strNumeric, regExPattern);
        }
Tuesday, May 27, 2008 2:27:28 PM UTC  #    Comments [0]    |  Trackback
 Thursday, May 22, 2008
        /// <summary>
        /// Information about the currently executing assembly, this is used to determine
        /// our version, etc.
        /// </summary>
        private System.Reflection.Assembly m_assemblyInfo;

        public string version
        {
            get
            {
                string ourVersion = string.Empty;
                //if running the deployed application, you can get the version
                //  from the ApplicationDeployment information. If you try
                //  to access this when you are running in Visual Studio, it will not work.
                if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                    ourVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();
                else
                    if (m_assemblyInfo != null)
                        ourVersion = m_assemblyInfo.GetName().Version.ToString();
                return ourVersion;
            }
        }

 
Thursday, May 22, 2008 8:14:17 PM UTC  #    Comments [0]    |  Trackback
 Wednesday, May 21, 2008
 Monday, April 21, 2008

http://www.developerfusion.co.uk/show/2936/4/

   1:  using System;
   2:  using System.IO;
   3:  using System.Runtime.Serialization.Formatters.Soap;
   4:  using System.Reflection;
   5:  using System.Collections;
   6:   
   7:  [Serializable]
   8:  public class User{
   9:      [ValidLength(4,8,Message="UserID should be between 4 and 8 characters long")]
  10:      public string userID;
  11:   
  12:      [ValidLength(4,8,Message="Password should be between 4 and 6 characters long")]
  13:      public string password;
  14:   
  15:      [ValidLength(4,60)]
  16:      public string email;
  17:      public string city;
  18:   
  19:      public void Save(string fileName){
  20:           FileStream s=new FileStream(fileName,FileMode.Create);
  21:           SoapFormatter sf=new SoapFormatter();
  22:           sf.Serialize(s,this);
  23:      }
  24:   
  25:      static void Main(string[] args){
  26:           User u=new User();
  27:           u.userID="first";
  28:           u.password="Zxfd12Qs";
  29:           u.email=".com";
  30:           u.city="";
  31:           Validator v=new Validator();
  32:           if(!v.IsValid(u)){
  33:                foreach(string message in v.Messages)
  34:                     Console.WriteLine(message);
  35:           }
  36:           else {u.Save("user.txt");}
  37:      }
  38:  }
 
   1:  [AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
   2:  public class ValidLengthAttribute : Attribute{
   3:      private int _min;
   4:      private int _max;
   5:      private string _message;
   6:   
   7:      public ValidLengthAttribute(int min,int max){
   8:           _min=min;
   9:           _max=max;
  10:      }
  11:   
  12:      public string Message{
  13:           get {return(_message);}
  14:           set {_message=value;}
  15:      }
  16:   
  17:      public string Min{
  18:           get{return _min.ToString();}
  19:      }
  20:   
  21:      public string Max{
  22:           get{return _max.ToString();}
  23:      }
  24:   
  25:      public bool IsValid(string theValue){
  26:           int length=theValue.Length;
  27:           if(length >= _min && length <= _max) return true;
  28:           return false;
  29:      }
  30:  }

 

   1:  public class Validator{
   2:      public ArrayList Messages=new ArrayList();
   3:   
   4:      public bool IsValid(object anObject){
   5:           bool isValid=true;
   6:           FieldInfo[] fields = anObject.GetType().GetFields(BindingFlags.Public|BindingFlags.Instance);
   7:                foreach (FieldInfo field in fields)
   8:                     if(!isValidField(field,anObject)) isValid=false;
   9:                return isValid;
  10:      }
  11:   
  12:      private bool isValidField(FieldInfo aField,object anObject){
  13:           object[] attributes=aField.GetCustomAttributes(typeof(ValidLengthAttribute),true);
  14:           if(attributes.GetLength(0) ==0) return true;
  15:           return isValidField(aField,anObject,(ValidLengthAttribute)attributes[0]);
  16:      }
  17:   
  18:      private bool isValidField(FieldInfo aField, object anObject,ValidLengthAttribute anAttr){
  19:           string theValue=(string)aField.GetValue(anObject);
  20:           if (anAttr.IsValid(theValue)) return true;
  21:           addMessages(aField,anAttr);
  22:           return false;
  23:      }
  24:   
  25:      private void addMessages(FieldInfo aField,ValidLengthAttribute anAttr){
  26:           if(anAttr.Message !=null){
  27:                Messages.Add(anAttr.Message);
  28:                return;
  29:           }
  30:           Messages.Add("Invalid range for "+aField.Name+". Valid range is between "+anAttr.Min+" and "+anAttr.Max);
  31:      }
  32:  }
 
Monday, April 21, 2008 3:35:05 PM UTC  #    Comments [0]    |  Trackback
 Thursday, April 17, 2008

Databinding issue in WPF: with solution

http://www.lhotka.net/weblog/DataBindingIssueInWPFWithSolution.aspx#a89bf0c78-2bfc-4872-89b3-5499c4cbd0ae

(Important: set UpdateSourceTrigger to LostFocus for textbox)

Thursday, April 17, 2008 7:56:42 PM UTC  #    Comments [0]    |  Trackback
Thursday, April 17, 2008 4:16:48 AM UTC  #    Comments [0]    |   |  Trackback
 Tuesday, April 15, 2008
Copyright © 2009 Kevin Mocha. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.
Pick a theme: