/// <summary>
        /// When the expander expands, need to put the error message in the
        /// adorner layer because the controls below it, may have their own
        /// adorner validation error messages, this places the expander
        /// popup on top of all other adorder layer elements.
        /// </summary>
        void _objErrorsExpander_Expanded(object sender, RoutedEventArgs e)
        {
            //this forces the ErrorMessage to be reread from it's source
            this.InvalidateProperty(ErrorMessageProperty);

            var expanderGrid = VisualTreeSearchAssistant.FindVisualChild <Grid>(_errorsExpander);

            _errorsExpanderAdornerLayer = AdornerLayer.GetAdornerLayer(expanderGrid);

            String[] delimiter     = { Environment.NewLine };
            String[] errorMessages = this.ErrorMessage.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
            Array.Sort(errorMessages);

            var txt = new TextBlock {
                Width = this.Width, TextWrapping = TextWrapping.Wrap, Text = string.Join(Environment.NewLine + Environment.NewLine, errorMessages), Padding = new Thickness(5), Foreground = this.ErrorPopUpForeground, Background = this.ErrorPopUpBackground, Effect = new System.Windows.Media.Effects.DropShadowEffect {
                    ShadowDepth = 2
                }
            };

            //need to move the TextBlock down below the expander and indent a little
            var obj = new TranslateTransform(5, _errorsExpander.ActualHeight + 2);

            txt.RenderTransform           = obj;
            _textBlockAdorner             = new TextBlockAdorner(expanderGrid, txt);
            _textBlockAdorner.MouseLeave -= _objTextBlockAdorner_MouseLeave;
            _textBlockAdorner.MouseEnter -= _objTextBlockAdorner_MouseEnter;
            _errorsExpanderAdornerLayer.Add(_textBlockAdorner);
        }
 /// <summary>
 /// When the expander collapses, need to remove the TextBlock adorner
 /// </summary>
 void _objErrorsExpander_Collapsed(object sender, RoutedEventArgs e)
 {
     if (_errorsExpanderAdornerLayer != null)
     {
         _textBlockAdorner.MouseLeave -= _objTextBlockAdorner_MouseLeave;
         _textBlockAdorner.MouseEnter -= _objTextBlockAdorner_MouseEnter;
         _errorsExpanderAdornerLayer.Remove(_textBlockAdorner);
         _textBlockAdorner           = null;
         _errorsExpanderAdornerLayer = null;
     }
 }