private static void AddMarkupValue(this Paragraph paragraph, string value, XamlStyles styles) { var markupString = value.Substring(1, value.Length - 2); var indexOfSpace = markupString.IndexOf(' '); var markupType = indexOfSpace < 0 ? markupString : markupString.Substring(0, indexOfSpace); paragraph.AddRun("{", styles.DelimiterStyle); paragraph.AddRun(markupType, styles.NameStyle); if (indexOfSpace >= 0) { paragraph.AddMarkupBody(markupString.Substring(indexOfSpace), styles); } paragraph.AddRun("}", styles.DelimiterStyle); }
private static void AddMarkupBody(this Paragraph paragraph, string value, XamlStyles styles) { var indexOfNonspace = FindNonspaceInMarkup(value); var spaceText = indexOfNonspace < 0 ? value : value.Substring(0, indexOfNonspace); paragraph.AddRun(spaceText, styles.AttributeValueStyle); if (indexOfNonspace < 0) { return; } value = value.Substring(indexOfNonspace); if (value.StartsWith("{}")) { var indexOfComma = FindCommaInMarkup(value); var text = indexOfComma < 0 ? value : value.Substring(0, indexOfComma); paragraph.AddRun(text, styles.TextStyle); if (indexOfComma < 0) { return; } value = value.Substring(indexOfComma); } else if (value.StartsWith("{")) { var indexOfClosedBrace = FindClosedBraceInMarkup(value); if (indexOfClosedBrace < 0) { paragraph.AddRun(value, styles.ErrorStyle); return; } paragraph.AddMarkupValue(value.Substring(0, indexOfClosedBrace), styles); value = value.Substring(indexOfClosedBrace + 1); } // TODO: // Path=Title, StringFormat={}{0}AVS, ElementName=window paragraph.AddRun(value, styles.AttributeValueStyle); }
/// <summary> /// Fill flow document paragraph with syntax colored XAML. /// </summary> /// <param name="paragraph">paragraph to be filled</param> /// <param name="xaml">xaml to colorize</param> /// <param name="styles">styles used for syntax coloring</param> public static void FillParagraph(this Paragraph paragraph, string xaml, XamlStyles styles) { using (var reader = new XmlTextReader(xaml, XmlNodeType.Document, null)) { var indent = 0; var tagOpened = false; while (reader.Read()) { if (reader.IsStartElement()) // opening tag, e.g. <Button { if (tagOpened) { // new line for child element paragraph.Inlines.Add(new LineBreak()); } // indentation paragraph.AddRun(new string(' ', indent * 4), styles.TextStyle); paragraph.AddRun("<", styles.DelimiterStyle); paragraph.AddRun(reader.Name, styles.NameStyle); if (reader.HasAttributes) { // write tag attributes while (reader.MoveToNextAttribute()) { paragraph.AddRun(" " + reader.Name, styles.AttributeStyle); paragraph.AddRun("=", styles.DelimiterStyle); paragraph.AddRun("\"", styles.QuotesStyle); string value; if (reader.Name == "TargetType") // target type fix - should use the Type MarkupExtension { value = "{x:Type " + reader.Value + "}"; } else { value = reader.Value; } paragraph.AddAttributeValue(value, styles); paragraph.AddRun("\"", styles.QuotesStyle); } reader.MoveToElement(); } if (reader.IsEmptyElement) // empty tag, e.g. <Button /> { paragraph.AddRun(" />", styles.DelimiterStyle); paragraph.Inlines.Add(new LineBreak()); tagOpened = false; --indent; } else // non-empty tag, e.g. <Button> { paragraph.AddRun(">", styles.DelimiterStyle); tagOpened = true; } ++indent; } else // closing tag, e.g. </Button> { --indent; // text content of a tag, e.g. the text "Do This" in <Button>Do This</Button> if (reader.NodeType == XmlNodeType.Text) { var content = reader.ReadContentAsString(); if (content.IndexOfAny(new[] { '\r', '\n' }) >= 0 && indent > 0) { // indentation paragraph.AddRun(new string(' ', indent * 4), styles.TextStyle); } paragraph.AddRun(content, styles.TextStyle); } else if (indent > 0) { // indentation paragraph.AddRun(new string(' ', indent * 4), styles.TextStyle); } paragraph.AddRun("</", styles.DelimiterStyle); paragraph.AddRun(reader.Name, styles.NameStyle); paragraph.AddRun(">", styles.DelimiterStyle); paragraph.Inlines.Add(new LineBreak()); tagOpened = false; } } } }
private static void AddAttributeValue(this Paragraph paragraph, string value, XamlStyles styles) { if (value.StartsWith("{}")) { paragraph.AddRun(value, styles.TextStyle); } else if (value.StartsWith("{") && value.EndsWith("}")) { paragraph.AddMarkupValue(value, styles); } else { paragraph.AddRun(value, styles.AttributeValueStyle); } }
public XamlView() { InitializeComponent(); _styles = new XamlStyles { DelimiterStyle = new Style(typeof(Run)) { Setters = { new Setter(TextElement.ForegroundProperty, new SolidColorBrush(Color.FromRgb(240, 241, 242))) } }, NameStyle = new Style(typeof(Run)) { Setters = { new Setter(TextElement.ForegroundProperty, new SolidColorBrush(Color.FromRgb(103, 139, 176))) } }, QuotesStyle = new Style(typeof(Run)) { Setters = { new Setter(TextElement.ForegroundProperty, new SolidColorBrush(Color.FromRgb(235, 118, 0))) } }, TextStyle = new Style(typeof(Run)) { Setters = { new Setter(TextElement.ForegroundProperty, new SolidColorBrush(Colors.White)) } }, AttributeStyle = new Style(typeof(Run)) { Setters = { new Setter(TextElement.ForegroundProperty, new SolidColorBrush(Color.FromRgb(184, 201, 218))) } }, AttributeValueStyle = new Style(typeof(Run)) { Setters = { new Setter(TextElement.ForegroundProperty, new SolidColorBrush(Color.FromRgb(235, 118, 0))) } }, ConstantValueStyle = new Style(typeof(Run)) { Setters = { new Setter(TextElement.ForegroundProperty, new SolidColorBrush(Color.FromRgb(254, 204, 34))) } }, ErrorStyle = new Style(typeof(Run)) { Setters = { new Setter(TextElement.ForegroundProperty, new SolidColorBrush(Color.FromRgb(254, 51, 51))) } }, GeneralStyle = new Style(typeof(Paragraph)) { Setters = { new Setter(TextElement.BackgroundProperty, new SolidColorBrush(Color.FromRgb(34, 40, 42))), new Setter(Block.TextAlignmentProperty, TextAlignment.Left), new Setter(TextElement.FontFamilyProperty, new FontFamily("Consolas")) } } }; _tabs = new ObservableCollection <PropertyXaml>(); Tabs.ItemsSource = _tabs; Tabs.SetBinding(Selector.SelectedItemProperty, new Binding(SelectedTabProperty.Name) { Source = this, Mode = BindingMode.TwoWay }); DocView.SetBinding(FlowDocumentScrollViewer.DocumentProperty, new Binding(SelectedTabProperty.Name + "." + PropertyXaml.DocumentProperty.Name) { Source = this, FallbackValue = null }); }