2016-06-08 86 views
2

我在Xamarin表单Mvvm中遇到问题。我有2个不同的布局,说布局1和布局2是由一个共同的ViewModel限制。 Layout1包含多个标签,我使用for循环在xaml.cs文件中动态生成,并使用SetBinding绑定每个Label'sTextProperty。 Layout2包含一个按钮。更改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>的某个位置,您可以从这两个布局访问......您的View Model看起来像是合乎逻辑的位置。然后当你点击你的按钮时,你可以找到你想要改变并更改它的文本的特定Label。您可能需要重新加载您的列表。

但是我认为更好的方法是使用ListView而不是StackLayout。然后,您可以为包含一个标签的ListView设置ItemTemplate。然后您可以设置一个ObservableCollection<T>的对象用作ListView.ItemsSource。你会想制作一些具有Text属性的自定义对象,或者任何你想调用将保存标签文本的属性。最好使用TT的对象而不是ObservableCollection<string>,因为对字符串类型的更改不会反映在ListView项目中,而是更改为对象的属性(假设您将其设置为Bindable属性)将反映在那些与该财产有关的控制中。所以,简单地说,像(在视图模型):

// 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将只是一个简单的类,只有一个叫BindablePropertyText

设置这样,你可以指定你的ListView.ItemsSourcedummyLabelContentsObservableCollection,然后当你添加项目到ObservableCollection,ListView控件会自动更新。此外,由于在ObservableCollection中使用了具有可绑定文本属性的自定义类型,因此当文本属性发生更改时,ListView中的项目也应相应更新。