2014-07-26 64 views
3

我有一個XAML文件,我想用變量替換字段名,所以我可以爲我的應用程序提供更多語言的翻譯支持。在XAML中使用靜態函數綁定

我目前在我的應用程序中使用翻譯的方式是一樣的東西Translation.getString(「字符串名稱」)(翻譯是一個靜態類,靜態的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喇嘛」將運行它作爲一個功能Translation.getString(「BLA」),並使用返回的字符串爲我所期望的翻譯影響。

這是可能以某種方式?

有沒有其他的「商業標準」,通常這是通常完成的?

回答

3

您可以通過創建自定義MarkupExtension並使用它來代替綁定。

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'}"/> 

Ofcourse你必須在根級別這樣定義命名空間local

xmlns:local="clr-namespace:WpfApplication1" 

替換WpfApplication1與類TranslateString的實際名稱空間。

1

我知道,這種問題沒有商業標準。

如果對XAML有任何真實性,那就是它很冗長。這並不總是一件壞事,但它意味着即使是使用簡單的自定義行爲的控件也可能非常棘手。

雖然有一個recommended workflow for globalizing an application,但它很複雜,我沒有幫你,實際上包括使用和修改微軟提供的示例應用程序作爲工作流程的一部分的說明。

另一種選擇是像平時一樣開發,use a tool like Sisulizer來代理本地化。當然,這很容易,但它的成本來自金錢。

使用這兩種工作流程,你可以在Application.Resources定義字符串,並引用它們作爲DynamicResource

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文件填充。

+0

我把這個和接受的答案結合起來,它完全符合我想要的,完美的方式。 – user3595338