簡體   English   中英

在XAML中使用占位符進行WPF本地化擴展

[英]Using placeholders in XAML for WPF Localization Extension

我在我的程序中使用WPF Localization Extension。 為了減少類似資源的數量(例如“以米為單位的長度”,“以千米為單位的長度”等),我想使用占位符並在XAML代碼中設置它們。

我想過這樣的事情

資源“UI_Length”的值

Length in {0}

在CodeBehind中,使用String.Format非常容易

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

但是如何在XAML中添加另一個字符串甚至是另一個資源條目?

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

根據WPF中資源文件的Binding占位符,似乎可以,但我無法讓它運行標簽

[更新]

我設法添加了兩個資源值。 訣竅是在Label.Content中添加一個TextBlock。 見鏈接

        <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");

我得到一個“綁定在使用后無法更改”。 錯誤。 有沒有類似的方法來使用幾個資源值,仍然能夠在運行時切換語言?

[更新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保持空白。

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM