2016-06-08 2 views
2

Я столкнулся с проблемой в формах Xamarin Mvvm. У меня есть два разных макета: Layout1 и Layout2, которые ограничены общей ViewModel. Layout1 содержит несколько ярлыков, которые я динамически создаю для цикла в файле xaml.cs и связывают каждый Label'sTextProperty с помощью SetBinding. В макете 2 есть кнопка.Изменить значение метки при нажатии кнопки в Xamarin MVVM

Теперь я хочу изменить текст конкретной метки при нажатии кнопки.

Layout1.xaml

<StackLayout xmlns="http://xamarin.com/schemas/2014/forms" 
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
x:Class="Layout1"> 

<StackLayout x:Name="ParentStack"> 

// dynamic Labels to be added here.. 

</StackLayout>   
</StackLayout> 

Layout1.xaml.cs

public partial class Layout1: StackLayout 
{ 
    public Label dummyLabel; 
    public Layout1() 
    { 
     InitializeComponent(); 
     for (int i = 0; i < 3; i++) 
     { 
     dummyLabel= new Label 
     { 
      Text = " ", 
     }; 
     dummyLabel.SetBinding (Label.TextProperty,"PhaseValue"); 
     parentRowCells.Children.Add(dummyLabel); 
     var tapGestureRecognizer_1 = new TapGestureRecognizer();     
      tapGestureRecognizer_1.SetBinding(TapGestureRecognizer.CommandProperty,"LabelClicked"); 
      tapGestureRecognizer_1.CommandParameter = dummyLabel; 
      dummyLabel.GestureRecognizers.Add(tapGestureRecognizer_1); 
      } 

      } 

     } 

Layout2.Xaml

<StackLayout xmlns="http://xamarin.com/schemas/2014/forms" 
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
x:Class="Layout2"> 

<StackLayout x:Name="ParentStack"> 
<Button Command={Binding ButtonClickedCommand} Text="Click Me" /> 
</StackLayout>   

</StackLayout> 

ViewModel.cs

class ViewModel 
{ 

    public Label label = new Label(); 
    public string textstring = "new text string"; 
    ICommand _labelClicked; 
    public ICommand LabelClicked 
    { 
     get 
     { 
      this._labelClicked= this._labelClicked?? new Command(s => 
      { 

       label = s as Label; 
      label.Text = "new text"; //this change the text of particular    label when clicked but i need it from button clicked event from another layout. 
       // here I'm getting the instance of label which i clicked on label. 

      }); 

      return this._labelClicked; 
     } 
    } 

    public ICommand ButtonClickedCommand{ protected set; get; } 



    public ViewModel() 
    { 

     this.ButtonClickCommand = new Command<Button>((key) => 
     { 

     //here I want to change the value of label when button command is clicked. 
     aa.Text = "this is not changing the text"; 
     }); 

    } 



} 

Любая помощь в этом или мне нужно, чтобы следить за другим шаблоном .. ??

ответ

0

Моей первой мыслью было добавить каждый Label, который вы добавляете в List<Label> где-нибудь, с которым вы можете получить доступ с обеих макетов ... ваша модель просмотра будет выглядеть как логическое место. Затем, когда вы нажимаете кнопку, вы можете найти конкретный номер Label, текст которого вы хотите изменить и изменить. Вероятно, вам придется перезагрузить свой список.

Однако я считаю, что лучшим способом было бы использовать ListView вместо StackLayout. Тогда у вас может быть ItemTemplate для ListView, который включает в себя один ярлык. Затем вы можете создать ObservableCollection<T> объектов для использования в качестве ListView.ItemsSource. Вы хотели бы создать какой-то пользовательский объект, у которого есть свойство Text, или что бы вы хотели назвать свойством, которое будет содержать текст для ярлыков. Лучше использовать объект для T в ObservableCollection<T>, а не использовать ObservableCollection<string>, потому что изменения в строковом типе не отражаются в элементе ListView, но изменяются на свойство объекта (предполагая, конечно, что вы превращаете его в свойство Bindable) будут отражены в тех элементах управления, которые связаны с этим свойством. Таким образом, в двух словах, что-то вроде (в вашем ViewModel):

// Class level variable 
ObservableCollection<CustomType> dummyLabelContents; 

// then either in the ViewModel constructor or somewhere else: 
dummyLabelContents = new ObservableCollection<CustomType>(); 

CustomType dummyText; 
for (int i = 0; i < 3; i++) 
{ 
    dummyText = new CustomType 
    { 
     Text = " ", 
    }; 
} 
dummyLabelContents.Add(dummyText); 

И ваш CustomType будет просто простой класс с только BindableProperty называется Text.

Настройка, как это, вы можете назначить ваш ListView.ItemsSource быть dummyLabelContentsObservableCollection, а затем всякий раз, когда вы добавляете элемент в ObservableCollection, то ListView будет обновляться автоматически. Кроме того, поскольку использование настраиваемого типа с привязываемым текстовым свойством в ObservableCollection, когда это свойство текста изменяется, элемент в ListView также должен соответствующим образом обновлять.

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