在XAML中使用静态函数绑定

时间:2014-07-26 16:03:03

标签: c# wpf xaml .net-4.5

我有一个XAML文件,我想用变量替换字段名称,这样我就可以为我的应用程序提供更多语言的翻译支持。

我目前在我的应用程序中使用翻译的方式类似于Translation.getString(“stringname”)(翻译是一个带有静态getString函数的静态类,它从资源文件中获取翻译后的字符串)

现在对于xaml部分我有这样的事情:

<TextBlock Text="Some string for translation" VerticalAlignment="Center"/>

我可以这样做:

代码:

var translatedString = Translation.getString("stringname")

的Xaml:

<TextBlock Text="{Binding translatedString}" VerticalAlignment="Center"/>

但这是非常丑陋和冗长的。我可以以某种方式直接从xaml访问该函数吗?

如:

<TextBlock Text="{CustomBinding stringname}" VerticalAlignment="Center"/>

我在项目的某个地方指定使用“CustomBinding bla”将其作为函数Translation.getString(“bla”)运行,并使用返回的字符串作为我想要的翻译效果。

这有可能吗?

是否还有其他“商业标准”,通常会这样做?

3 个答案:

答案 0 :(得分:4)

您可以通过创建自定义 MarkupExtension 并使用它代替Binding来实现这一目标。

public class TranslateString : MarkupExtension
{
    public string Value { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (String.IsNullOrWhiteSpace(Value))
            return Value;
        return Translation.getString(Value);
    }
}

现在,你可以像这样在XAML中使用它:

<TextBlock Text="{local:TranslateString Value='Some string for translation'}"/>

当然,您必须在根级别定义名称空间 local ,如下所示:

xmlns:local="clr-namespace:WpfApplication1"

WpfApplication1替换为TranslateString类的实际命名空间。

答案 1 :(得分:1)

据我所知,这类问题没有商业标准。

如果有关于XAML的任何事情,那就是它的冗长。这并不总是坏事,但这意味着即使是具有简单自定义行为的控件也可能很棘手。

有一个recommended workflow for globalizing an application,但它很复杂,而且我没有意外,实际上包含了使用和修改微软提供的示例应用程序作为工作流程一部分的说明。

另一种选择是像往常一样开发,use a tool like Sisulizer来代理本地化。当然,这更容易,但成本来得钱。

使用任一工作流程,您都可以在Application.Resources中定义字符串,并将其引用为DynamicResource

答案 2 :(得分:1)

我已经实现了这个:

public partial class App : Application
{
    Dictionary<string, string> localizer;

    public App()
    {
        localizer = new Dictionary<string, string>() { { "loc", "locdsasdasd" } };
        //LoadLocalizer(); 
        this.Resources.Add("Localizer", localizer);
    }
}

<强> LocBinding.cs

 using System;
 using System.Windows.Data;
 using System.Collections.Generic;

namespace Stackoverflow
{
public class LocBinding : Binding
{
    static Dictionary<string, string> localizer=((Dictionary<string,string>)   
     (App.Current.Resources["Localizer"]));

    public LocBinding(string property)
    {
        if (string.IsNullOrWhiteSpace(property))
            throw new ArgumentNullException("binding path is null");

        string value;
        if (localizer.TryGetValue(property, out value))
            this.Source = value;
        else
            throw new KeyNotFoundException(property + "key is not defined in       
            localizer");
    }
}
}

<强> .xaml.cs

<Window x:Class="Stackoverflow.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Stackoverflow"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Label Content="{local:LocBinding loc}"/>
</Grid>

本地化程序中的这一个值仅用于测试。但实际上这些值将从数据库或xml或.resx文件中填充。