XAML - 显示格式化的ComboBoxItems

时间:2016-01-19 20:49:25

标签: c# wpf xaml

我有一个WPF应用程序。在这个应用程序中,我有一个ComboBox。 ComboBox显示algabra公式列表。我希望我的学生能够选择一个公式。公式包括上标。出于这个原因,我想我需要使用像这样的TextBlock:

<TextBlock>
    <Run>x</Run>
    <Run Typography.Variants="Superscript">2</Run>
    <Run>+ 2xy </Run>
</TextBlock>

我将这些公式放在

public class Formula
{
    public string Text { get; set; }
    public Formula(string text) 
    {
        this.Text = text;
    }
}

public class MyViewModel
{
    public MyViewModel() 
    {
        this.Formulas = new List<Formula>
        {
            new Formula("<TextBlock><Run>x</Run><Run Typography.Variants=\"Superscript\">2</Run><Run>+ 2xy </Run></TextBlock>"),
            new Formula("<TextBlock><Run>x</Run><Run Typography.Variants=\"Superscript\">3</Run><Run>+ 3xy </Run></TextBlock>")
        };
    }  
}

然后我尝试将这些公式显示为ComboBoxItems。目前,我有以下内容:

<ComboBox ItemsSource="{Binding Path=Formulas}" DisplayMemberPath="Text" />

此方法不显示格式化的公式。有没有办法绑定ComboBoxItems来显示格式化的值?如果是这样,怎么样?

谢谢!

1 个答案:

答案 0 :(得分:3)

我建议查看能够正确显示公式的库(类似的答案here

虽然如果你想让这种方法有效,你可以通过以下方式实现。

<Window x:Class="BindFormulas.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindFormulas"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:XamlTextToObjectConverter x:Key="XamlTextToObjectConverter" />
    </Window.Resources>

    <StackPanel>
        <ComboBox ItemsSource="{Binding Path=Formulas}">
            <ComboBox.ItemTemplate>
                <DataTemplate DataType="local:Formula">
                    <ContentControl Content="{Binding Text, Converter={StaticResource XamlTextToObjectConverter}}" />
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </StackPanel>
</Window>

将XAML文本转换为实际对象的转换器:

public class XamlTextToObjectConverter : IValueConverter
{
    private static readonly Regex Regex = new Regex("(<.*?)>(.*)(</.*?>)", RegexOptions.Compiled);

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var xamlText = value as string;

        if (xamlText != null)
        {
            var xamlTextWithNamespace = Regex.Replace(xamlText, "$1 xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">$2$3");
            try
            {
                return XamlReader.Parse(xamlTextWithNamespace);
            }
            catch (Exception) // catch proper exceptions here, not just Exception
            {
                return value;
            }
        }
        else
        {
            return value;
        }
    }

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

end result

同样,对于正确执行此操作的库,您可能会更好:)

出于多种原因,这种做法是错误的:

Formula课程可能不应该了解TextBlockRun等内容。这不是模特类的关注点。 此外,我确信你可以提供一个XAML字符串,它将使转换器跳闸。

那就是说,如果这将是一个非常简单的应用程序,你将100%确定XAML字符串可以正确转换,那么也许这种方法也可以。