2017-02-08 16 views
4

Учитывая следующее ViewModel ...Xamarin Forms - заставить управление, чтобы обновить значение от связывания

public class NameEntryViewModel 
{ 
    public NameEntryViewModel() 
    { 
     Branding = new Dictionary<string, string>(); 

     Branding.Add("HeaderLabelText", "Welcome to the app"); 
    } 

    public Dictionary<string, string> Branding { get; set; } 
} 

Обязанных страницы ...

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="Monaco.Forms.Views.NameEntryPage"> 

     <Label Text="{Binding Branding[HeaderLabelText]}" /> 

</ContentPage> 

Когда страница приходит вверх этикетку получите текст «Добро пожаловать в приложение». Это отлично работает и вписывается в наш план по настройке и глобализации нашего приложения. Затем в этом примере статичный словарь брендинга статируется, но в реальном мире он инициализируется данными из служебного вызова.

Однако, если пользователь хочет переключить язык на испанский, нам нужно, чтобы каждая связанная метка обновлялась до нового значения. Достаточно легко сбросить словарь брендинга и заполнить его испанскими переводами, но как мы можем заставить элементы управления обновляться из связанных источников?

Я пытаюсь избежать привязки данных в двух направлениях здесь b/c, мы не хотим, чтобы служебные данные кода создавали свойство backing для каждого свойства Text элементов управления. Следовательно, мы привязываемся к словарю ценностей.

ОТВЕТ

Я принял ответ ниже, но я не использовал традиционный метод установки свойства. Вместо этого, когда пользователь хочет переключить другой язык, теперь у нас есть централизованный обработчик, который заполняет наш словарь, а затем уведомляет об изменении словаря. Мы используем MVVMCross, но вы можете перевести стандартные формы ...

public MvxCommand CultureCommand 
    { 
     get 
     { 
      return new MvxCommand(async() => 
      { 
       _brandingService.ToggleCurrentCulture(); 
       await ApplyBranding(); // <-- this call repopulates the Branding property 
       RaisePropertyChanged(() => Branding); 
      }); 
     } 
    } 
+2

Вы можете поднять событие PropertyChanged на Брендинг собственности и обновит все, что связывается с Брендинг или любой Binding, содержащий Брендинг на своем пути. –

ответ

6

Как @BillReiss упоминалось вы должны использовать OnPropertyChanged событие наследуют NameEntryViewModel из этого класса:

public class BaseViewModel : INotifyPropertyChanged 
{ 

    protected BaseViewModel() 
    { 

    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged ([CallerMemberName] string propertyName = null) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
      handler (this, new PropertyChangedEventArgs (propertyName)); 
    } 
} 

И создать частная собственность, что вы можете назначить вам публичной собственности что-то вроде:

Dictionary<string, string> _branding = new Dictionary<string, string>(); 
public Dictionary<string, string> Branding 
{ 
    get 
    { 
     return _branding; 
    } 
    set 
    { 
     _branding = value; 
     OnPropertyChanged(nameof(Branding)); 
    } 
} 

И с этим каждый раз, когда вы устанавливаете свойство Брендинг будет пусть Vi а что-то изменилось! Иногда, если вы делаете это на задней нити вы должны использовать Device.BeginInvokeOnMainThread()

 Смежные вопросы

  • Нет связанных вопросов^_^