WPF绑定StringFormat中的&符号

时间:2013-03-22 18:08:52

标签: wpf data-binding binding wpf-4.0

我正在尝试创建一个字符串格式,其中包含一个包含&符号的文字字符串。我试过&和&放大器; (没有空格)但两者都会导致VS2010设计器出现异常。以下是我正在使用的内容:

Text="{Binding Path=LearningOpportunities, StringFormat='Sharing & Learning Opportunitites:\{0\}'}"

如果我使用'&',它会告诉我“实体引用或以&符号开头的序列'&'必须以分号“;”结束。如果我使用& amp;,它得到一个FormatException:“Index(从零开始)必须大于或等于零且小于参数列表的大小。”我一直在远离WPF进行Web开发一段时间,所以我感觉有点生疏。我怎样才能使这个工作?

编辑:有很多关于逃避成为罪魁祸首的猜测,据我所知,这都是不正确的。因此,为了解决这个问题,有效的方法是行不通的,将&符号排除在等式之外:

有效的格式:

StringFormat=Sharing and learning opportunitites:\{0\}
StringFormat='Sharing and learning opportunitites:\{0\}'
StringFormat={}Sharing and learning opportunitites:{0}
StringFormat='{}Sharing and learning opportunitites:{0}'
StringFormat=Sharing and learning opportunitites:{0}
StringFormat='Sharing and learning opportunitites:{0}'

不起作用的格式:

StringFormat=Sharing and learning opportunitites:{}{0}
StringFormat=Sharing and learning opportunitites:{{0}}  (Outputs literal "{0}")

总而言之,您可以通过在字符串的开头处放置开始和结束括号{}来转义字符串中的所有大括号,或者您可以使用反斜杠转义单个大括号。令人惊讶的是,它在没有转义大括号的情况下仍然有效,但语法着色在Visual Studio中非常难看。为了避免丑陋的语法着色,您可以在格式字符串周围使用单引号。

因此,当转义停止时,问题是在格式字符串中添加&符会导致异常,无论是否转义。转义和未转义之间的唯一区别是它提供了一个不同的例外。

3 个答案:

答案 0 :(得分:2)

EDITEDITEDIT:

啊哈!原来是苹果酒设计界的血腥虫!

证明:

尝试这一系列的XAML行:

<StackPanel>
    <!-- should show '$YoMamma' -->
    <TextBlock Text="{Binding Path=Value, StringFormat=&#x24;{0}}"/>
    <!-- should show '%YoMamma' -->
    <TextBlock Text="{Binding Path=Value, StringFormat=&#x25;{0}}"/>
    <!-- should show '&YoMamma', but crashes the designer -->
    <!--<TextBlock Text="{Binding Path=Value, StringFormat=&#x26;{0}}"/>-->
    <!-- should show '"YoMamma', but crashes the designer -->
    <!--<TextBlock Text="{Binding Path=Value, StringFormat=&#x27;{0}}"/>-->
    <!-- should show '(YoMamma' -->
    <TextBlock Text="{Binding Path=Value, StringFormat=&#x28;{0}}"/>
    <!-- should show ')YoMamma' -->
    <TextBlock Text="{Binding Path=Value, StringFormat=&#x29;{0}}"/>

</StackPanel>

我提交了一个错误报告来连接,我们会看看是否有人回复: https://connect.microsoft.com/VisualStudio/feedback/details/782059/cider-vs2010-designer-bug-with-binding-using-escaped-entities-in-stringformat

这个答案的其余部分是半成熟的,尽管可能有用,因为“bug”出现在设计师身上。

这里要记住的是XAML XML,所以你需要相应地对&符号进行编码:

&amp;

应该有效,以及:

&#38;

编辑:

啊,是的 - 正如评论中来回讨论的那样,问题不在于&符号本身,而在于周围的替换标记的“逃逸” Binding的大括号 - 为了解决这个问题,你实际上有三个选择:

编辑2:呸,我认为降价可能不喜欢我的帖子(无论如何我都错了) - 让我们看看我是否可以拼凑一个完整的例子:

以防万一,这里也是一个pastebin链接: http://pastebin.com/yfrpvxs1

所以说我们有一个像这样的上下文对象:

public class Foo : INotifyPropertyChanged
{
    private string _value;
    public string Value
    {
        get { return _value; }
        set { _value = value; FireNpc("Value"); }
    }
    private decimal _numberValue;
    public decimal NumberValue
    {
        get { return _numberValue; }
        set { _numberValue = value; FireNpc("NumberValue"); }
    }
    private DateTime _dateValue;
    public DateTime DateValue
    {
        get { return _dateValue; }
        set { _dateValue = value; FireNpc("DateValue"); }
    }
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    private void FireNpc(string name)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}

窗口代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new Foo()
            {
                Value = "YoMamma", 
                DateValue = DateTime.Now, 
                NumberValue = 3.14m
            };
    }
}

我们是XAML!

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <!-- should show '#1:Foo & Bar:YoMamma' -->
        <TextBlock Text="{Binding Path=Value, StringFormat=#1:Foo &amp; Bar:{0}}"/>

        <!-- should show '#2:Foo & Bar:YoMamma' -->
        <TextBlock>
            <TextBlock.Text>
                <Binding Path="Value" StringFormat="#2:Foo &amp; Bar:{0}"/>
            </TextBlock.Text>
        </TextBlock>

        <!-- will actually show the '{' and '}', so 'Foo & Bar:{0}' -->
        <TextBlock Text="{Binding Path=Value, StringFormat=Foo &amp; Bar:{{0}}}"/>

        <!-- default 'custom' (there's a fun oxymoron) format - should be '$3.14' -->
        <TextBlock Text="{Binding Path=NumberValue, StringFormat=c}"/>

        <!-- custom 'custom' (bear with me) format -->
        <TextBlock Text="{Binding Path=DateValue, StringFormat=MM/dd/yyyy}"/>

        <!-- multi parameter formatting-->
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding StringFormat="As of {2:MM/dd/yyyy}, {0} cost {1:c}">
                    <Binding Path="Value"/>
                    <Binding Path="NumberValue"/>
                    <Binding Path="DateValue"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </StackPanel>
</Window>

现在,捎带MultiBinding,我们可以做些蠢事 - 让我们把它添加到我们的上下文中:

    // Heh...don't actually do this, naturally...
    private string _ampersandValue;
    public string AmpersandValue
    {
        get { return _ampersandValue; }
        set { _ampersandValue = value; FireNpc("AmpersandValue"); }
    }


    this.DataContext = new Foo()
        {
            Value = "YoMamma", 
            DateValue = DateTime.Now, 
            NumberValue = 3.14m,
            AmpersandValue = "&"
        };

并添加此XAML:

    <!-- And a crazy-person's method, using multi parameter formatting-->
    <TextBlock>
        <TextBlock.Text>
            <MultiBinding StringFormat="{}{0} {1} {0} = {0}">
                <Binding Path="Value"/>
                <Binding Path="AmpersandValue"/>
            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>

答案 1 :(得分:0)

您需要使用&amp;作为&符号,并删除充当转义字符的\。您还有额外的'个字符,这些字符不是必需的。请尝试以下方法:

Text="{Binding Path=LearningOpportunities, StringFormat=Sharing &amp; Learning Opportunitites:{0}}"

答案 2 :(得分:0)

任何时候我想在绑定中使用StringFormat,而我的格式包含额外的文本或空格,我在前面添加了一组额外的curley括号:

StringFormat={}Sharing and learning opportunitites:{0}

我知道我在网上看到过使用其他方法的参考资料,但他们都曾经一度失败过。我认为不同版本的WPF支持不同的StringFormat语法,因此根据您使用的版本,其他语法也可以正常工作,但上面是我发现的唯一一种相当普遍的语法。

此外,您还希望使用&amp;来转义&字符

StringFormat={}Sharing &amp; learning opportunitites:{0}