如何在 WPF 应用程序中将 XAML 显示为文本

How to show XAML as text in WPF application

我们正在更新包含自定义样式控件的图库 WPF 应用程序。设计是有一个切换来显示这些自定义控件后面的 XAML,以便于参考和新同事的指南。

我目前实现它的方法是创建两个 .xaml 文件,一个只包含控件,一个包含控件和一个带有 XAML 编码的文本块,用于实现这些控件。

这不容易维护,因为引号、>、< 和其他字符在 XAML 字符串中不会转义。作为参考,这是我现在在 'Show code' 个视图之一中看到的内容:

<TextBlock Visibility="Collapsed" Margin="5" Text="&lt;controls:AutoCompleteTagBox&#10;
           Name=&quot;AutoCompleteTagBoxWithStrings&quot;&#10;
           Margin=&quot;5&quot;&#10;
           ItemsSource=&quot;{Binding Names}&quot;&#10;
           FilterMode=&quot;Contains&quot; /&gt;&#10;
           &lt;ListBox&#10;
           ItemsSource=&quot;{Binding ElementName=AutoCompleteTagBoxWithStrings, Path=SelectedItems}&quot;&#10;
           Grid.Column=&quot;1&quot;&#10;
           BorderBrush=&quot;{StaticResource Blue}&quot; BorderThickness=&quot;1&quot; /&gt;"/>

如您所见,它看起来不太好,更新其中一个控件后,您现在有三个地方需要更改 XAML。

下一步只是绑定 TextBlock 可见性并将其从 'Collapsed' 切换到 'Visible'。但我想知道是否有一种方法可以在文本块中显示 XAML 而无需手写字符串。

提前感谢您的建议!

根据 XAMIMAX 的评论,您可以使用简单的转换器将 xaml 保存为使用 XamlWriter 的字符串,并为简洁起见去除 xmlns 名称空间。

public class XamlConverter : IValueConverter
{
    public readonly Regex xmlnsRegex = new Regex("xmlns=\".+\"");

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var source = value as FrameworkElement;
        if (source != null)
        {
            //Save xaml and strip xmlns namespaces
            var xaml = xmlnsRegex.Replace(System.Windows.Markup.XamlWriter.Save(source), "");

            return xaml;
        }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

用法示例

<StackPanel>
    <StackPanel.Resources>
        <converters:XamlConverter x:Key="Converter_Xaml"/>
    </StackPanel.Resources>
    <Button x:Name="SourceButton" Content="Click Me" Margin="10"/>
    <TextBlock Text="{Binding ElementName=SourceButton, Converter={StaticResource Converter_Xaml}}" TextWrapping="Wrap"/>
</StackPanel>