2016-08-24 75 views
3

我在我的程序中使用了WPF本地化擴展。 爲了減少類似資源的數量(比如「以米爲單位的長度」,「以千米爲單位的長度」等),我想使用佔位符並將它們設置爲XAML代碼。在XAML中爲WPF本地化擴展使用佔位符

我想過這樣的事情

的資源 「UI_Length」

Length in {0} 

在代碼隱藏的價值,這是用的String.Format

String.Format(
     LocalizeDictionary.Instance.GetLocalizedObject("UI_Length", null, LocalizeDictionary.Instance.Culture).ToString(), 
     "Meters"); 

卻怎麼也相當容易我在XAML中添加另一個String或甚至另一個資源項?

<Label x:Name="Label" Content="{lex:LocText Key=UI_Length}, Meters" HorizontalAlignment="Left" VerticalAlignment="Top"/> 

根據Binding placeholder from resource file in WPF這似乎是可能的,但我不能讓它運行一個標籤

[更新]

我設法增加兩個資源的值。 訣竅是在Label.Content中添加一個TextBlock。 see Link

 <Label Grid.Row="1"> 
      <Label.Content> 
       <TextBlock> 
        <TextBlock.Text> 
         <MultiBinding StringFormat="{}{0} [{1}]"> 
          <Binding Source="{lex:LocText Key=UI_Length}" /> 
          <Binding Source="{lex:LocText Key=UI_MeterShort}" /> 
         </MultiBinding> 
        </TextBlock.Text> 
       </TextBlock> 
      </Label.Content> 
     </Label> 

但我在這裏仍然有問題。在啓動此工作正常,但當我嘗試切換語言與

LocalizeDictionary.Instance.Culture = new CultureInfo("de-DE"); 

我得到一個「已使用後綁定無法更改。」錯誤。 是否有類似的方式來使用severall資源值,並仍然能夠在運行時切換語言?

[更新2]

我試圖從Liero的建議,但仍然有一個問題在這裏。

在我的MainView中,我將DataContext設置爲MainViewModel。 VM有一個LocalizedTexts實例。在更改ViewModel中的語言後,我調用RaisePropertiesChanged(),但沒有得到任何輸出。

TextBlock的綁定到LengthInMeters

<TextBlock Text="{Binding LocalizedTexsts.LengthInMeters}" /> 

,我改變了語言之後調用RaisePorpertyChanged:

public void ChangeLanguage(string culture) 
    { 
     LocalizeDictionary.Instance.Culture = new CultureInfo(culture); 
     _localizedTexts.RaisePropertyChanged(); 
    } 

LengthInMeters看起來是這樣的:

public string LengthInMeters 
{ 
    get 
    { 
     return String.Format(
        LocalizeDictionary.Instance.GetLocalizedObject(
         "UI_Length", null, 
         LocalizeDictionary.Instance.Culture).ToString(), 
        LocalizeDictionary.Instance.GetLocalizedObject(
         "UI_Meters", null, 
         LocalizeDictionary.Instance.Culture).ToString() 
       ); 
    } 
} 

但TextBlock的保持空着。

回答

3

首先,你可以縮短這樣的綁定:

<TextBlock Text="{Binding Source={lex:LocText Key=UI_MeterShort}, 
          StringFormat={lex:LocText Key=UI_Length}}" /> 

其次,如果要更新綁定,當語言的變化,那麼你需要找到在代碼隱藏TextBlock的和更新綁定手動使用BindingExpression.UpdateTarget()方法。但這很奇怪,不是嗎?

或者,您可以通過刪除所有內容並創建新內容來刷新整個窗口。我的意思是像從窗口中刪除UserControl和創建新的UserControl。

但是,這兩種解決方案都很奇怪,因爲它只是解決了由WPF中的綁定錯誤引起的問題。讓我建議更好的方法。

public class LocalizedTexts: INotifyPropertyChanged 
{ 
    public event PropertyChanged; 


    public LengthInMeters { get { return String.Format(...); } } 

    public LengthInKilometers {get { return String.Format(...); } } 


    public void RaisePropertiesChanged() 
    { 
     foreach (var property in this.GetType().GetProperties()) 
     { 
     PropertyChanged(this, new PropertyChangedEventArgs(property.Name)) 
     } 
    } 
} 

現在,您可以向數據綁定和LocalizedTexts當語言的變化,只需要調用RaisePropertiesChanged()

用法:

<Application.Resources> 
    <l:LocalizedTexts x:Key="LocalizedTexts" /> 
</Application.Resources> 

<TextBlock Text="{Binding LengthInMeters, Source={StaticResource LocalizedTexts}}" /> 


<!-- instead of using StaticResource, you can add l:LocalizedTexts as a property to your viewmodel --> 
<TextBlock Text="{Binding LocalizedTexts.LengthInMeters}" /> 
+0

我想你的建議的方法,但這裏仍然有一個問題。我所做的是:在我的MainView中,我將DataContext設置爲MainViewModel。 VM有一個LocalizedTexts實例。在更改ViewModel中的語言後,我調用RaisePropertiesChanged(),但沒有得到任何輸出。 =>請看更新2瞭解更多細節。 – 4pinsGigabit