【问题标题】:Refresh UI after new Language Xamarin新语言 Xamarin 后刷新 UI
【发布时间】:2019-05-16 02:27:41
【问题描述】:

Re-evaluate all values in xaml page calculated by a markup-extension

我尝试实施此解决方案,但我有一个 ObservableCollection,其中包含要在我的 MasterDetails 页面的列表视图中绑定的标题,但它不起作用。我真的不知道如何实现这一点,但只有一个标签我成功了。如果有人可以帮助我。谢谢

我的物品清单:

public ObservableCollection<MainMenuViewItem> MenuItems {
            get {
                return new ObservableCollection<MainMenuViewItem>(new[]
                {
                    new MainMenuViewItem { Id = 0, Title = Translator.TranslatorInstance["lblHome"], TargetType=typeof(HybridWebView),ViewModelType=HybridViewTypeEnum.Home },
                    new MainMenuViewItem { Id = 1, Title = Translator.TranslatorInstance["lblListOfDeliverySlip"], TargetType=typeof(HybridWebView),ViewModelType=HybridViewTypeEnum.ListDeliverySlip },
                    new MainMenuViewItem { Id = 2, Title = Translator.TranslatorInstance["lblSettings"], TargetType=typeof(ParametersView)}
                });
            }
        }

我的看法

<ListView Grid.Row="1" x:Name="MenuListPage" SeparatorVisibility="None" 
              HasUnevenRows="true" ItemsSource="{Binding MenuItems}" >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Padding="15,10" HorizontalOptions="FillAndExpand">
                                <Label VerticalOptions="FillAndExpand" 
                                VerticalTextAlignment="Center" 
                                Text="{Binding Title, StringFormat='{0}',Source={x:Static translate:Translator.TranslatorInstance}}" 
                                FontSize="24"/>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

translationExtension 类

/// <summary>
        /// Current culture info
        /// </summary>
        public static CultureInfo CultureInfoApp { get; private set; }

        // Path of folder where is store each file language + Name of file without .en ( language code ) 
        private const string ResourceId = "Landauer.Mobile.Ressources.Language.LanguageRessource"; 

        // Instanciation differed of Ressourcemanager
        public static readonly Lazy<ResourceManager> RessourceManagerLanguage = new Lazy<ResourceManager>(() => new ResourceManager(ResourceId, IntrospectionExtensions.GetTypeInfo(typeof(TranslateExtension)).Assembly));

        /// <summary>
        /// Match to the name of the label into .resx file
        /// </summary>
        public string Text { get; set; }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="text"></param>
        public TranslateExtension()
        {
            if (Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.Android)
            {
                // Get dependency in each specific platform
                CultureInfoApp = DependencyService.Get<ILanguage>().GetCurrentCultureInfo();
            }
            //Text = text;
        }

        object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
        {
            return ProvideValue(serviceProvider);
        }

        public BindingBase ProvideValue(IServiceProvider serviceProvider)
        {
            var binding = new Binding
            {
                Mode = BindingMode.OneWay,
                Path = $"[{Text}]",
                Source = Translator.TranslatorInstance,
            };
            return binding;
        }

最后是我的翻译课:

public static Translator TranslatorInstance => _uniqueInstance;

        /// <summary>
        /// When TranslateExtension you create new Binding(), call this "Callback"
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public string this[string text]
        {
            get
            {
                return TranslateExtension.RessourceManagerLanguage.Value.GetString(text, TranslateExtension.CultureInfoApp);
            }
        }

        /// <summary>
        /// Implementation of notifications
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// At each time you set language use this method to refresh UI
        /// </summary>
        public void Invalidate()
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
        }

【问题讨论】:

  • 如果您不费心向我们展示您在做什么,我们将无法帮助您。如果没有任何代码说明您实际尝试做什么,对问题的模糊描述是没有用的。
  • @Jason 好的,对不起,我忘记了,我已经修改了。
  • 你的翻译类是否实现了 INotifyPropertyChanged?当语言改变时你调用 Invlaidate() 吗?
  • 如果在实例化 MenuItems 列表时已经调用了 Translator.TranslatorInstance,为什么还要在 XAML 中调用它?根据我对您的代码的理解,您调用了两次,第一个已经进行了翻译。如果是这种情况,为什么不使用 RaisePropertyChanged/InvalidProperty 重新创建列表?
  • @Jason 是的,我这样做。是的,翻译器实现 INotifyPropertyChanged

标签: user-interface xamarin.forms refresh translation


【解决方案1】:

更改语言时需要设置资源的文化。

当您设置文化时,您的语言实例类也应该调用属性更改处理程序。

所以在实例类中创建一个方法,如下所示,并在您更改语言设置时调用..

public void SetCultureInfo(CultureInfo cultureInfo)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
    }

语言更改时,代码应如下所示

var ci = CultureInfo.CreateSpecificCulture("ar");
                NativeLangUtil.SetLocale(ci); // updating Native 
                Resx.Lang.Strings.Culture = ci; //For .net Resources to work
                Application.Current.Properties["Lang"] = ci.TwoLetterISOLanguageName;// 
                LangResourceLoader.Instance.SetCultureInfo(ci); //for our use

您可以找到sample implementation here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    相关资源
    最近更新 更多