bool CtrlSpace(ITextEditor editor, XamlCompletionContext context)
 {
     if (context.Description == XamlContextDescription.InComment ||
         context.Description == XamlContextDescription.InCData ||
         context.ActiveElement == null)
     {
         return(false);
     }
     if (!context.InAttributeValueOrMarkupExtension)
     {
         XamlCompletionItemList list = generator.CreateListForContext(context);
         string starter = editor.GetWordBeforeCaretExtended().TrimStart('/');
         if (context.Description != XamlContextDescription.None && !string.IsNullOrEmpty(starter))
         {
             if (starter.Contains("."))
             {
                 list.PreselectionLength = starter.Length - starter.IndexOf('.') - 1;
             }
             else
             {
                 list.PreselectionLength = starter.Length;
             }
         }
         editor.ShowCompletionWindow(list);
         return(true);
     }
     // DO NOT USE generator.CreateListForContext here!!! results in endless recursion!!!!
     if (context.Attribute != null)
     {
         if (!DoMarkupExtensionCompletion(context))
         {
             var completionList = new XamlCompletionItemList(context);
             completionList.PreselectionLength = editor.GetWordBeforeCaretExtended().Length;
             if ((context.ActiveElement.Name == "Setter" || context.ActiveElement.Name == "EventSetter") && (context.Attribute.Name == "Property" || context.Attribute.Name == "Value"))
             {
                 DoSetterAndEventSetterCompletion(context, completionList);
                 editor.ShowCompletionWindow(completionList);
             }
             else if ((context.ActiveElement.Name.EndsWith("Trigger", StringComparison.Ordinal) || context.ActiveElement.Name == "Condition") && context.Attribute.Name == "Value")
             {
                 DoTriggerCompletion(context, completionList);
                 editor.ShowCompletionWindow(completionList);
             }
             else if (!DoAttributeCompletion(context, completionList))
             {
                 DoXmlAttributeCompletion(context, completionList);
             }
             return(completionList.Items.Any());
         }
         return(true);
     }
     return(false);
 }
        bool DoAttributeCompletion(XamlCompletionContext context, XamlCompletionItemList completionList)
        {
            XamlAstResolver resolver = new XamlAstResolver(compilation, context.ParseInformation);
            ITextEditor     editor   = context.Editor;
            var             mrr      = resolver.ResolveAttribute(context.Attribute) as MemberResolveResult;

            if (mrr != null && mrr.Type.Kind != TypeKind.Unknown)
            {
                completionList.Items.AddRange(generator.MemberCompletion(context, mrr.Type, string.Empty));
                editor.ShowInsightWindow(generator.MemberInsight(mrr));
                editor.ShowCompletionWindow(completionList);
                switch (mrr.Type.FullName)
                {
                case "System.Windows.PropertyPath":
                    string start = editor.GetWordBeforeCaretExtended();
                    int    index = start.LastIndexOfAny(PropertyPathTokenizer.ControlChars);
                    if (index + 1 < start.Length)
                    {
                        start = start.Substring(index + 1);
                    }
                    else
                    {
                        start = "";
                    }
                    completionList.PreselectionLength = start.Length;
                    break;

                case "System.Windows.Media.FontFamily":
                    string text      = context.ValueStartOffset > -1 ? context.RawAttributeValue.Substring(0, Math.Min(context.ValueStartOffset, context.RawAttributeValue.Length)) : "";
                    int    lastComma = text.LastIndexOf(',');
                    completionList.PreselectionLength = lastComma == -1 ? context.ValueStartOffset : context.ValueStartOffset - lastComma - 1;
                    break;
                }
            }

            return(completionList.Items.Any());
        }
		public CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch)
		{
			compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
			resolver = new XamlResolver(compilation);
			
			XamlCompletionContext context = XamlContextResolver.ResolveCompletionContext(editor, ch);
			XamlCompletionItemList list;
			
			if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData)
				return CodeCompletionKeyPressResult.None;
			
			switch (ch) {
				case '<':
					context.Description = (context.Description == XamlContextDescription.None) ? XamlContextDescription.AtTag : context.Description;
					list = generator.CreateListForContext(context);
					editor.ShowCompletionWindow(list);
					return CodeCompletionKeyPressResult.Completed;
				case '>':
					return CodeCompletionKeyPressResult.None;
				case '\'':
				case '"':
					if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) {
						// count all " or ' chars before the next > char
						int search = editor.Caret.Offset + 1;
						int endMarkerCount = 1;
						char curCh = editor.Document.GetCharAt(search);
						while (search < editor.Document.TextLength - 1 && curCh != '>') {
							if (curCh == ch)
								endMarkerCount++;
							search++;
							curCh = editor.Document.GetCharAt(search);
						}
						// if the count is odd we need to add an additional " or ' char
						if (endMarkerCount % 2 != 0) {
							editor.Document.Insert(editor.Caret.Offset, ch.ToString());
							editor.Caret.Offset--;
							CtrlSpace(editor);
							return CodeCompletionKeyPressResult.Completed;
						}
					}
					break;
				case '{': // starting point for Markup Extension Completion
					if (context.Attribute != null
					    && XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)
					    && !(context.RawAttributeValue.StartsWith("{}", StringComparison.OrdinalIgnoreCase) && context.RawAttributeValue.Length != 2)) {
						
						if (editor.SelectionLength != 0)
							editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
						
						editor.Document.Insert(editor.Caret.Offset, "{}");
						editor.Caret.Offset--;
						
						this.CtrlSpace(editor);
						return CodeCompletionKeyPressResult.EatKey;
					}
					break;
				case '.':
					switch (context.Description) {
						case XamlContextDescription.AtTag:
						case XamlContextDescription.InTag:
							if (context.ActiveElement != null) {
								list = generator.CreateListForContext(context);
								editor.ShowCompletionWindow(list);
								return CodeCompletionKeyPressResult.Completed;
							}
							break;
						case XamlContextDescription.InMarkupExtension:
							if (DoMarkupExtensionCompletion(context))
								return CodeCompletionKeyPressResult.Completed;
							break;
						case XamlContextDescription.InAttributeValue:
							if (editor.SelectionLength != 0)
								editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
							
							editor.Document.Insert(editor.Caret.Offset, ".");
							
							this.CtrlSpace(editor);
							return CodeCompletionKeyPressResult.EatKey;
					}
					break;
				case '(':
				case '[':
					if (context.Description == XamlContextDescription.InAttributeValue) {
						if (editor.SelectionLength != 0)
							editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
						
						if (ch == '(')
							editor.Document.Insert(editor.Caret.Offset, "()");
						if (ch == '[')
							editor.Document.Insert(editor.Caret.Offset, "[]");
						editor.Caret.Offset--;
						
						CtrlSpace(editor);
						return CodeCompletionKeyPressResult.EatKey;
					}
					break;
				case ':':
					if (context.ActiveElement != null && XmlParser.GetQualifiedAttributeNameAtIndex(editor.Document.Text, editor.Caret.Offset) == null) {
						if (context.Attribute != null && !context.Attribute.Name.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase)) {
							list = generator.CreateListForContext(context);
							list.PreselectionLength = editor.GetWordBeforeCaretExtended().Length;
							editor.ShowCompletionWindow(list);
							return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion;
						}
					}
					break;
				case '/': // ignore '/' when trying to type '/>'
					return CodeCompletionKeyPressResult.None;
				case '=':
					if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) {
						int searchOffset = editor.Caret.Offset;
						
						if (editor.SelectionLength != 0)
							editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
						
						while (searchOffset < editor.Document.TextLength - 1) {
							searchOffset++;
							if (!char.IsWhiteSpace(editor.Document.GetCharAt(searchOffset)))
								break;
						}
						
						if (searchOffset >= editor.Document.TextLength || editor.Document.GetCharAt(searchOffset) != '"') {
							editor.Document.Insert(editor.Caret.Offset, "=\"\"");
							editor.Caret.Offset--;
						} else {
							editor.Document.Insert(editor.Caret.Offset, "=");
							editor.Caret.Offset++;
						}
						
						CtrlSpace(editor);
						return CodeCompletionKeyPressResult.EatKey;
					} else {
						DoMarkupExtensionCompletion(context);
						return CodeCompletionKeyPressResult.Completed;
					}
				default:
					if (context.Description != XamlContextDescription.None && !char.IsWhiteSpace(ch)) {
						string starter = editor.GetWordBeforeCaretExtended();
						if (!string.IsNullOrEmpty(starter))
							return CodeCompletionKeyPressResult.None;
						string attributeName = (context.Attribute != null) ? context.Attribute.Name : string.Empty;
						
						if (!attributeName.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase)) {
							return CtrlSpace(editor, context)
								? CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion
								: CodeCompletionKeyPressResult.None;
						}
						return CodeCompletionKeyPressResult.None;
					}
					break;
			}
			
			return CodeCompletionKeyPressResult.None;
		}
		bool CtrlSpace(ITextEditor editor, XamlCompletionContext context)
		{
			if (context.Description == XamlContextDescription.InComment
			    || context.Description == XamlContextDescription.InCData
			    || context.ActiveElement == null) {
				return false;
			}
			if (!context.InAttributeValueOrMarkupExtension) {
				XamlCompletionItemList list = generator.CreateListForContext(context);
				string starter = editor.GetWordBeforeCaretExtended().TrimStart('/');
				if (context.Description != XamlContextDescription.None && !string.IsNullOrEmpty(starter)) {
					if (starter.Contains(".")) {
						list.PreselectionLength = starter.Length - starter.IndexOf('.') - 1;
					} else {
						list.PreselectionLength = starter.Length;
					}
				}
				editor.ShowCompletionWindow(list);
				return true;
			}
			// DO NOT USE generator.CreateListForContext here!!! results in endless recursion!!!!
			if (context.Attribute != null) {
				if (!DoMarkupExtensionCompletion(context)) {
					var completionList = new XamlCompletionItemList(context);
					completionList.PreselectionLength = editor.GetWordBeforeCaretExtended().Length;
					if ((context.ActiveElement.Name == "Setter" || context.ActiveElement.Name == "EventSetter") && (context.Attribute.Name == "Property" || context.Attribute.Name == "Value")) {
						DoSetterAndEventSetterCompletion(context, completionList);
						editor.ShowCompletionWindow(completionList);
					} else if ((context.ActiveElement.Name.EndsWith("Trigger", StringComparison.Ordinal) || context.ActiveElement.Name == "Condition") && context.Attribute.Name == "Value") {
						DoTriggerCompletion(context, completionList);
						editor.ShowCompletionWindow(completionList);
					} else if (!DoAttributeCompletion(context, completionList)) {
						DoXmlAttributeCompletion(context, completionList);
					}
					return completionList.Items.Any();
				}
				return true;
			}
			return false;
		}
        public bool CtrlSpace(ITextEditor editor)
        {
            XamlCompletionContext context = CompletionDataHelper.ResolveCompletionContext(editor, ' ');

            context.Forced = trackForced;

            if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData)
            {
                return(false);
            }

            if (context.ActiveElement != null)
            {
                if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset) && context.Description != XamlContextDescription.InAttributeValue)
                {
                    XamlCompletionItemList list = CompletionDataHelper.CreateListForContext(context);
                    string starter = editor.GetWordBeforeCaretExtended().TrimStart('/');
                    if (context.Description != XamlContextDescription.None && !string.IsNullOrEmpty(starter))
                    {
                        if (starter.Contains("."))
                        {
                            list.PreselectionLength = starter.Length - starter.IndexOf('.') - 1;
                        }
                        else
                        {
                            list.PreselectionLength = starter.Length;
                        }
                    }
                    editor.ShowCompletionWindow(list);
                    return(true);
                }
                else
                {
                    // DO NOT USE CompletionDataHelper.CreateListForContext here!!! results in endless recursion!!!!
                    if (context.Attribute != null)
                    {
                        if (!DoMarkupExtensionCompletion(context))
                        {
                            var completionList = new XamlCompletionItemList(context);
                            completionList.PreselectionLength = editor.GetWordBeforeCaretExtended().Length;

                            if ((context.ActiveElement.Name == "Setter" || context.ActiveElement.Name == "EventSetter") &&
                                (context.Attribute.Name == "Property" || context.Attribute.Name == "Value"))
                            {
                                DoSetterAndEventSetterCompletion(context, completionList);
                            }
                            else if ((context.ActiveElement.Name.EndsWith("Trigger") || context.ActiveElement.Name == "Condition") && context.Attribute.Name == "Value")
                            {
                                DoTriggerCompletion(context, completionList);
                            }
                            else
                            {
                                if (context.Attribute.Name == "xml:space")
                                {
                                    completionList.Items.AddRange(new[] { new SpecialCompletionItem("preserve"),
                                                                          new SpecialCompletionItem("default") });
                                }

                                var mrr = XamlResolver.Resolve(context.Attribute.Name, context) as MemberResolveResult;
                                if (mrr != null && mrr.ResolvedType != null)
                                {
                                    completionList.Items.AddRange(CompletionDataHelper.MemberCompletion(context, mrr.ResolvedType, string.Empty));
                                    editor.ShowInsightWindow(CompletionDataHelper.MemberInsight(mrr));
                                    if (mrr.ResolvedType.FullyQualifiedName == "System.Windows.PropertyPath")
                                    {
                                        string start = editor.GetWordBeforeCaretExtended();
                                        int    index = start.LastIndexOfAny(PropertyPathTokenizer.ControlChars);
                                        if (index + 1 < start.Length)
                                        {
                                            start = start.Substring(index + 1);
                                        }
                                        else
                                        {
                                            start = "";
                                        }
                                        completionList.PreselectionLength = start.Length;
                                    }
                                    else if (mrr.ResolvedType.FullyQualifiedName == "System.Windows.Media.FontFamily")
                                    {
                                        string text      = context.ValueStartOffset > -1 ? context.RawAttributeValue.Substring(0, Math.Min(context.ValueStartOffset, context.RawAttributeValue.Length)) : "";
                                        int    lastComma = text.LastIndexOf(',');
                                        completionList.PreselectionLength = lastComma == -1 ? context.ValueStartOffset : context.ValueStartOffset - lastComma - 1;
                                    }
                                }
                            }

                            completionList.SortItems();

                            if (context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) ||
                                context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase))
                            {
                                completionList.Items.AddRange(CompletionDataHelper.CreateListForXmlnsCompletion(context.ProjectContent));
                            }

                            ICompletionListWindow window = editor.ShowCompletionWindow(completionList);

                            if ((context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) ||
                                 context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase)) && window != null)
                            {
                                window.Width = 400;
                            }

                            return(completionList.Items.Any());
                        }
                        return(true);
                    }
                }
            }
            return(false);
        }
        public CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch)
        {
            XamlCompletionContext  context = CompletionDataHelper.ResolveCompletionContext(editor, ch);
            XamlCompletionItemList list;

            if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData)
            {
                return(CodeCompletionKeyPressResult.None);
            }

            switch (ch)
            {
            case '<':
                context.Description = (context.Description == XamlContextDescription.None) ? XamlContextDescription.AtTag : context.Description;
                list = CompletionDataHelper.CreateListForContext(context);
                editor.ShowCompletionWindow(list);
                return(CodeCompletionKeyPressResult.Completed);

            case '>':
                return(CodeCompletionKeyPressResult.None);

            case '\'':
            case '"':
                if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset))
                {
                    // count all " or ' chars before the next > char
                    int  search         = editor.Caret.Offset + 1;
                    int  endMarkerCount = 1;
                    char curCh          = editor.Document.GetCharAt(search);
                    while (search < editor.Document.TextLength - 1 && curCh != '>')
                    {
                        if (curCh == ch)
                        {
                            endMarkerCount++;
                        }
                        search++;
                        curCh = editor.Document.GetCharAt(search);
                    }
                    // if the count is odd we need to add an additional " or ' char
                    if (endMarkerCount % 2 != 0)
                    {
                        editor.Document.Insert(editor.Caret.Offset, ch.ToString());
                        editor.Caret.Offset--;
                        this.CtrlSpace(editor);
                        return(CodeCompletionKeyPressResult.Completed);
                    }
                }
                break;

            case '{':                     // starting point for Markup Extension Completion
                if (context.Attribute != null &&
                    XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset) &&
                    !(context.RawAttributeValue.StartsWith("{}", StringComparison.OrdinalIgnoreCase) && context.RawAttributeValue.Length != 2))
                {
                    if (editor.SelectionLength != 0)
                    {
                        editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
                    }

                    editor.Document.Insert(editor.Caret.Offset, "{}");
                    editor.Caret.Offset--;

                    this.CtrlSpace(editor);
                    return(CodeCompletionKeyPressResult.EatKey);
                }
                break;

            case '.':
                switch (context.Description)
                {
                case XamlContextDescription.AtTag:
                case XamlContextDescription.InTag:
                    if (context.ActiveElement != null && !XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset))
                    {
                        list = CompletionDataHelper.CreateListForContext(context);
                        editor.ShowCompletionWindow(list);
                        return(CodeCompletionKeyPressResult.Completed);
                    }
                    break;

                case XamlContextDescription.InMarkupExtension:
                    if (DoMarkupExtensionCompletion(context))
                    {
                        return(CodeCompletionKeyPressResult.Completed);
                    }
                    break;

                case XamlContextDescription.InAttributeValue:
                    if (editor.SelectionLength != 0)
                    {
                        editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
                    }

                    editor.Document.Insert(editor.Caret.Offset, ".");

                    this.CtrlSpace(editor);
                    return(CodeCompletionKeyPressResult.EatKey);
                }
                break;

            case '(':
            case '[':
                if (context.Description == XamlContextDescription.InAttributeValue)
                {
                    if (editor.SelectionLength != 0)
                    {
                        editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
                    }

                    if (ch == '(')
                    {
                        editor.Document.Insert(editor.Caret.Offset, "()");
                    }
                    if (ch == '[')
                    {
                        editor.Document.Insert(editor.Caret.Offset, "[]");
                    }
                    editor.Caret.Offset--;

                    this.CtrlSpace(editor);
                    return(CodeCompletionKeyPressResult.EatKey);
                }
                break;

            case ':':
                if (context.ActiveElement != null && XmlParser.GetQualifiedAttributeNameAtIndex(editor.Document.Text, editor.Caret.Offset) == null)
                {
                    if (context.Attribute != null && !context.Attribute.Name.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase))
                    {
                        list = CompletionDataHelper.CreateListForContext(context);
                        list.PreselectionLength = editor.GetWordBeforeCaretExtended().Length;
                        editor.ShowCompletionWindow(list);
                        return(CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion);
                    }
                }
                break;

            case '/':                     // ignore '/' when trying to type '/>'
                return(CodeCompletionKeyPressResult.None);

            case '=':
                if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset))
                {
                    int searchOffset = editor.Caret.Offset;

                    if (editor.SelectionLength != 0)
                    {
                        editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
                    }

                    while (searchOffset < editor.Document.TextLength - 1)
                    {
                        searchOffset++;
                        if (!char.IsWhiteSpace(editor.Document.GetCharAt(searchOffset)))
                        {
                            break;
                        }
                    }

                    if (searchOffset >= editor.Document.TextLength || editor.Document.GetCharAt(searchOffset) != '"')
                    {
                        editor.Document.Insert(editor.Caret.Offset, "=\"\"");
                        editor.Caret.Offset--;
                    }
                    else
                    {
                        editor.Document.Insert(editor.Caret.Offset, "=");
                        editor.Caret.Offset++;
                    }

                    this.CtrlSpace(editor);
                    return(CodeCompletionKeyPressResult.EatKey);
                }
                else
                {
                    DoMarkupExtensionCompletion(context);
                    return(CodeCompletionKeyPressResult.Completed);
                }

            default:
                if (context.Description != XamlContextDescription.None && !char.IsWhiteSpace(ch))
                {
                    string starter = editor.GetWordBeforeCaretExtended();
                    if (!string.IsNullOrEmpty(starter))
                    {
                        return(CodeCompletionKeyPressResult.None);
                    }
                    trackForced = false;

                    string attributeName = (context.Attribute != null) ? context.Attribute.Name : string.Empty;

                    if (!attributeName.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase))
                    {
                        return(this.CtrlSpace(editor)
                                                                ? CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion
                                                                : CodeCompletionKeyPressResult.None);
                    }
                    trackForced = true;
                    return(CodeCompletionKeyPressResult.None);
                }
                break;
            }

            return(CodeCompletionKeyPressResult.None);
        }
Beispiel #7
0
        public XamlCompletionItemList CreateListForContext(XamlCompletionContext context)
        {
            XamlCompletionItemList list = new XamlCompletionItemList(context);

            ITextEditor editor = context.Editor;

            compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
            XamlAstResolver resolver = new XamlAstResolver(compilation, context.ParseInformation);

            switch (context.Description)
            {
            case XamlContextDescription.None:
                if (context.Forced)
                {
                    list.Items.AddRange(standardElements);
                    list.Items.AddRange(CreateElementList(context, false));
                    AddClosingTagCompletion(context, list, resolver);
                }
                break;

            case XamlContextDescription.AtTag:
                if ((editor.Caret.Offset > 0 && editor.Document.GetCharAt(editor.Caret.Offset - 1) == '.') || context.PressedKey == '.')
                {
                    list.Items.AddRange(CreateAttributeList(context, false));
                }
                else
                {
                    list.Items.AddRange(standardElements);
                    list.Items.AddRange(CreateElementList(context, false));
                    AddClosingTagCompletion(context, list, resolver);
                }
                break;

            case XamlContextDescription.InTag:
                string word = editor.GetWordBeforeCaretExtended();

                if (context.PressedKey == '.' || word.Contains("."))
                {
                    int pos = word.IndexOf(':');

                    string element       = word.Substring(pos + 1, word.Length - pos - 1);
                    string className     = word;
                    int    propertyStart = element.IndexOf('.');
                    if (propertyStart != -1)
                    {
                        element   = element.Substring(0, propertyStart).TrimEnd('.');
                        className = className.Substring(0, propertyStart + pos + 1).TrimEnd('.');
                    }

                    int          caretOffset = editor.Caret.Offset;
                    int          offset      = editor.Document.LastIndexOf(className, caretOffset - word.Length, word.Length, StringComparison.OrdinalIgnoreCase);
                    TextLocation loc         = editor.Document.GetLocation(offset);

                    XamlFullParseInformation info         = context.ParseInformation;
                    XamlResolver             nameResolver = new XamlResolver(compilation);
                    TypeResolveResult        trr          = nameResolver.ResolveExpression(className, context) as TypeResolveResult;
                    ITypeDefinition          typeClass    = trr != null?trr.Type.GetDefinition() : null;

                    if (typeClass != null && typeClass.HasAttached(true, true))
                    {
                        list.Items.AddRange(GetListOfAttached(context, typeClass, true, true));
                    }
                }
                else
                {
                    list.Items.AddRange(CreateAttributeList(context, true));
                    list.Items.AddRange(standardAttributes);
                }
                break;

            case XamlContextDescription.InAttributeValue:
                new XamlCodeCompletionBinding().CtrlSpace(editor);
                break;
            }

            list.SortItems();

            return(list);
        }
		public bool CtrlSpace(ITextEditor editor)
		{
			XamlCompletionContext context = CompletionDataHelper.ResolveCompletionContext(editor, ' ');
			context.Forced = trackForced;
			
			if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData)
				return false;
			
			if (context.ActiveElement != null) {
				if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset) && context.Description != XamlContextDescription.InAttributeValue) {
					XamlCompletionItemList list = CompletionDataHelper.CreateListForContext(context);
					string starter = editor.GetWordBeforeCaretExtended().TrimStart('/');
					if (context.Description != XamlContextDescription.None && !string.IsNullOrEmpty(starter)) {
						if (starter.Contains("."))
							list.PreselectionLength = starter.Length - starter.IndexOf('.') - 1;
						else
							list.PreselectionLength = starter.Length;
					}
					editor.ShowCompletionWindow(list);
					return true;
				} else {
					// DO NOT USE CompletionDataHelper.CreateListForContext here!!! results in endless recursion!!!!
					if (context.Attribute != null) {
						if (!DoMarkupExtensionCompletion(context)) {
							var completionList = new XamlCompletionItemList(context);
							completionList.PreselectionLength = editor.GetWordBeforeCaretExtended().Length;
							
							if ((context.ActiveElement.Name == "Setter" || context.ActiveElement.Name == "EventSetter") &&
							    (context.Attribute.Name == "Property" || context.Attribute.Name == "Value"))
								DoSetterAndEventSetterCompletion(context, completionList);
							else if ((context.ActiveElement.Name.EndsWith("Trigger") || context.ActiveElement.Name == "Condition") && context.Attribute.Name == "Value")
								DoTriggerCompletion(context, completionList);
							else {
								if (context.Attribute.Name == "xml:space") {
									completionList.Items.AddRange(new[] { new SpecialCompletionItem("preserve"),
									                              	new SpecialCompletionItem("default") });
								}
								
								var mrr = XamlResolver.Resolve(context.Attribute.Name, context) as MemberResolveResult;
								if (mrr != null && mrr.ResolvedType != null) {
									completionList.Items.AddRange(CompletionDataHelper.MemberCompletion(context, mrr.ResolvedType, string.Empty));
									editor.ShowInsightWindow(CompletionDataHelper.MemberInsight(mrr));
									if (mrr.ResolvedType.FullyQualifiedName == "System.Windows.PropertyPath") {
										string start = editor.GetWordBeforeCaretExtended();
										int index = start.LastIndexOfAny(PropertyPathTokenizer.ControlChars);
										if (index + 1 < start.Length)
											start = start.Substring(index + 1);
										else
											start = "";
										completionList.PreselectionLength = start.Length;
									} else if (mrr.ResolvedType.FullyQualifiedName == "System.Windows.Media.FontFamily") {
										string text = context.ValueStartOffset > -1 ? context.RawAttributeValue.Substring(0, Math.Min(context.ValueStartOffset + 1, context.RawAttributeValue.Length)) : "";
										int lastComma = text.LastIndexOf(',');
										completionList.PreselectionLength = lastComma == -1 ? context.ValueStartOffset + 1 : context.ValueStartOffset - lastComma;
									}
								}
							}
							
							completionList.SortItems();
							
							if (context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) ||
							    context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase))
								completionList.Items.AddRange(CompletionDataHelper.CreateListForXmlnsCompletion(context.ProjectContent));
							
							ICompletionListWindow window = editor.ShowCompletionWindow(completionList);
							
							if ((context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) ||
							     context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase)) && window != null)
								window.Width = 400;
							
							return completionList.Items.Any();
						}
						return true;
					}
				}
			}
			return false;
		}