【问题标题】:Ampersand in WPF Binding StringFormatWPF绑定StringFormat中的&符号
【发布时间】:2013-03-12 17:02:10
【问题描述】:

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

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

如果我使用 '&',它会告诉我“以 & 符号开头的实体引用或序列必须以分号 ';' 结尾”。如果我使用 & amp;,它会得到一个 FormatException:“索引(从零开始)必须大于或等于零并且小于参数列表的大小。”一段时间以来,我一直在远离 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 中语法着色非常难看。为避免难看的语法着色,您可以在格式字符串周围使用单引号。

因此,在停止转义后,问题在于在格式字符串中添加与号会导致异常,无论是否转义。转义和未转义的唯一区别是它给出了不同的异常。

【问题讨论】:

  • 嗯。在您尝试执行格式调用的地方添加代码 - 还有其他事情正在进行中。
  • 编辑显示我已经尝试过转义 & 符号。 @JerKimball,就是上面的代码。
  • 啊,我明白了……试试这个? StringFormat=Foo &酒吧:{}{0}
  • 有趣,就是这样。它表现得好像它会在我什至输入'&'的第二次得到异常,但这有效。谢谢!如果你把它作为答案,我会标记它。

标签: wpf data-binding binding wpf-4.0


【解决方案1】:

编辑编辑编辑:

啊哈!原来是苹果酒设计表面的一个该死的错误!

证明:

试试这个 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

这个答案的其余部分尚无定论,尽管可能有用,因为“错误”在设计者身上。

这里要记住的是,XAML XML,因此您需要相应地编码与符号:

&amp;

应该工作,以及:

&#38;

编辑:

啊,是的 - 正如在 cmets 中反复讨论的那样,问题不在于&符号本身,而在于周围替换标记的“转义” Binding 的大括号 - 要解决此问题,您实际上有三个选项:

编辑 2:呸,我认为 markdown 可能不喜欢我的帖子(而且我在某一点上错了) - 让我们看看我是否可以拼凑一个完整的例子:

以防万一,这里还有一个 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>

【讨论】:

  • 编辑把我的帖子弄乱了。我试着写我已经试过了。
  • 感谢您的有趣回答。但是你试过了吗?第一个和第三个 TextBlocks 中的 & 符号(& 的第一个字符)对我来说是一个异常:“System.FormatException 索引(从零开始)必须大于或等于零并且小于参数列表的大小。”
  • @xr280xr - 是的,所有这些都是我刚刚拼凑在一起的 wpf 应用程序中的 copypasta;它按预期显示...您收到此代码的错误??
  • 是的,复制并粘贴到测试项目中。使用 VS 2010 和 .NET Framework 4
  • @xr280xr 哈 - 确实找到了一件可能有用的东西……一个替代的 & 字符:&lt;TextBlock Text="{Binding Path=Value, StringFormat=A &amp;#xff06; B:{0}}"/&gt;
【解决方案2】:

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

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

【讨论】:

  • @xr280xr 已编辑 - 问题是不使用 &amp;amp; 并且还在...中添加了额外的 `` 字符。
  • 我认为 Reed 的思路是正确的:我认为是大括号把你搞砸了,而不是 & 号;检查我在 op 上添加的评论
  • 顺便说一句,Reed:根本原因实际上是一个设计错误;有趣有趣有趣...以及您所拥有的大脑参考手册中需要注意的事项;)
【解决方案3】:

每当我想在绑定中使用StringFormat,并且我的格式包含额外的文本或空格时,我都会在前面添加一组额外的花括号,如下所示:

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

我知道我在网上看到过使用其他方法的参考资料,但它们都曾让我失望过。我认为不同版本的 WPF 支持不同的 StringFormat 语法,因此根据您使用的版本,其他语法可能也可以,但以上是我发现的唯一一个相当普遍的语法。

此外,您还需要使用 &amp;amp; 转义 &amp; 字符

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

【讨论】:

    猜你喜欢
    • 2011-08-17
    • 2011-03-11
    • 2010-12-15
    • 2011-06-30
    • 2017-02-16
    • 2011-05-28
    • 1970-01-01
    • 2011-03-26
    • 1970-01-01
    相关资源
    最近更新 更多