gpt4 book ai didi

wpf - WPF 和本地化中的嵌入式超链接

转载 作者:行者123 更新时间:2023-12-04 21:14:35 25 4
gpt4 key购买 nike

我在 WPF 应用程序中有一个 TextBlock,我想向用户显示类似于以下内容的消息:

Retrygo back.

我可以这样做:

<TextBlock>
<Hyperlink Command="{Binding RetryCommand}">
<Run Text="Retry" />
</Hyperlink>
<Run Text=" or " />
<Hyperlink Command="{Binding GoBackCommand}">
<Run Text="go back." />
</Hyperlink>
</TextBlock>

但是这个方案对本地化不是很友好;在句子需要在本地化过程中重新排列的情况下,这尤其成问题。我更希望能够在 resx 文件中指定诸如 [Retry]({0}) 或 [go back.]({1})." 之类的内容,并将超链接动态插入到本地化的字符串。是否有一种简洁明了的方法来执行此操作?

在另一个应用程序中,我们使用了一个非常复杂的解决方案,涉及扩展 TextBlock 类和动态构造 Inlines 属性,但它似乎是一个应该是常见问题的大量代码。

相关问题:Is adding strings with placeholders (`{0}`) into resources a good idea? , How to embed links in localized text

最佳答案

所以我想一个解决方案是自定义控件。但是,我能够使用 IMultiValueConverter 来完成工作。

public class TextBlockFormatToHyperlinkConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values.Length >= 3)
{
var tblk = values[0] as TextBlock;
var format = values[1] as string;
var tokens = Tokenizer.ParseTokens(format);
int hyperLinkIndex = 0;
for (int i = 2; i < values.Length; i++)
{
var token = tokens.FirstOrDefault((p) => string.Equals(p.Value as string, "{" + hyperLinkIndex + "}"));
if (token != null)
{
token.Value = values[i];
}
hyperLinkIndex++;
}

tblk.Inlines.Clear();
foreach (var token in tokens)
{
if (token.Value is Hyperlink)
tblk.Inlines.Add((Hyperlink)token.Value);
else
tblk.Inlines.Add(new Run(token.Value as string));
}

return tblk;
}
return null;
}

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

private class Token
{
public object Value { get; set; }
public Token(object value)
{
Value = value;
}
}
private class HyperlinkToken : Token
{
public HyperlinkToken(object value) : base(value) { }
}

private static class Tokenizer
{
public static List<Token> ParseTokens(string format)
{
var tokens = new List<Token>();
var strings = Regex.Split(format, @"({\d+})");
foreach (var str in strings)
{
if (Regex.IsMatch(str, @"({\d+})"))
{
tokens.Add(new HyperlinkToken(str));
}
else
{
tokens.Add(new Token(str));
}
}
return tokens;
}
}
}

然后在 XAML 中我这样使用它:

<TextBlock x:Name="tblk_LogFileLink" TextWrapping="Wrap">
<TextBlock.Tag>
<MultiBinding Converter="{StaticResource TextBlockFormatToHyperlinkConverter}">
<Binding x:Name="textblock" ElementName="tblk_LogFileLink"/>
<Binding x:Name="formatString" Source="Click to open the {0}."/>
<Binding x:Name="firstHyperlink">
<Binding.Source>
<Hyperlink NavigateUri="{Binding LogPath}">
<Run Text="{x:Static localization:Resources.LBL_LOG_FILE}"/>
</Hyperlink>
</Binding.Source>
</Binding>
</MultiBinding>
</TextBlock.Tag>
</TextBlock>

如果您的字符串格式需要更多,您可以向 MultiBinding 添加多个超链接。

这让我能够本地化整个字符串,同时仍然提供超链接文本。

关于wpf - WPF 和本地化中的嵌入式超链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10694973/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com