Binding.IndexerName and Binding.ProvideValue in Xamarin Forms

Hey,

I am trying to implement the answer in this so question: http://stackoverflow.com/questions/40554561/re-evaluate-all-values-in-xaml-page-calculated-by-a-markup-extension/40567656#40567656

The problem is, that in xamarin forms 2 ingredients do not exist (or I have not found them yet):

  • Binding.IndexerName
  • Binding.ProvideValue()

Do these simply not exist in Xamarin forms? Can I somehow "emulate" them?

Thanks!
Nathan

Tagged:

Best Answer

Answers

  • AnnLeeAnnLee USMember ✭✭

    My master page listview item name not change even after translator.instance.invalidate();
    The label are changed but how can I change the listview item name?

  • theocangtheocang Member ✭✭✭
    edited May 2019

    @AnnLee Hey, have you find solution to this issue ? Thanks.

    @StephenClifton.9427 Thanks for your example but when I would only use : {translate:Translate NameBinding} it didn't refresh UI, but only with {Binding [lblLanguageOfApp], Source={x:Static translate:Translator.TranslatorInstance}}

  • AnnLeeAnnLee USMember ✭✭

    @theocang I use messaging service to call for master page to reinitialise for the value

  • BasuBasu USMember ✭✭

    @> @StephenClifton.9427 said:

    I'd tried to implement @Grx70's great proposed solution (see OP's StackOverflow link), but some of the classes and properties the example used are internal to Xamarin so couldn't be used in that way (as you've found)
    Picking up on their last comment though, was the clue to get it working, though not quite as elegantly as initially proposed, we can do this:

    public class TranslateExtension : IMarkupExtension<BindingBase>
    {     
        public TranslateExtension(string text)
        {
            Text = text;            
        }
        
        public string Text { get; set; }
        
        object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
        {
              return ProvideValue(serviceProvider);
        }
    
        public BindingBase ProvideValue(IServiceProvider serviceProvider)
        {
            var binding = new Binding
            {
              Mode = BindingMode.OneWay,
              Path = $"[{Text}]",
                  Source = Translator.Instance,
            };
        return binding;
        }        
    }
    

    and this the Translator class as initially proposed, but reproduced here for clarity with the GetString call:

    public class Translator : INotifyPropertyChanged
    {
        public string this[string text]
        {
      get
      {
          return Strings.ResourceManager.GetString(text, Strings.Culture);
      }
        }        
    
        public static Translator Instance { get; } = new Translator();
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void Invalidate()
        {
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
        }
    

    }


    Then as the original post suggested, instead of binding text with:
    {i18n:Translate Label_Text}

    Bind
    {Binding [Label_Text], Source={x:Static i18n:Translator.Instance}}

    I'd hit this right at the end of a project (adding the multiple languages), but using Visual Studio Community and Search/Replace with RegEx, the binding can be replaced across the project, replacing:
    \{resources:Translate (.*?)\}
    with:
    {Binding [$1], Source={x:Static core:Translator.Instance}}

    NOTE: The Regex assumes the 'resources' namespace for the original Translate macro, and 'core' namespace for the Translator class, you may have to update as appropriate.

    As the original StackOverflow post said, to trigger the update of languages you just then need to call:
    Translator.Instance.Invalidate()

    I appreciate this is a small tweak to @Grx70's otherwise great solution (I'm standing on the shoulders of giant's with this one), but I'm posting this here for any that follow with the same problem of getting this working.

    Could you please share me the code base, Even im also doing the same process, but im not getting how the xaml to extension is calling

    Thanks,
    Basappa

Sign In or Register to comment.