在Xamarin MVVM中单击按钮更改标签值

时间:2016-06-08 10:22:56

标签: xamarin xamarin.forms

我在Xamarin形成Mvvm时面临一个问题。我有两种不同的布局,比如Layout1和Layout2,它们与一个共同的ViewModel绑定在一起。 Layout1包含多个标签,我在xaml.cs文件中使用for循环动态生成,并使用SetBinding绑定每个Label' sTextProperty。 Layout2包含一个按钮。

现在,我想在点击按钮时更改特定标签的文字。

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";
        });

    }



}

这方面的任何帮助还是我需要遵循其他模式.. ??

1 个答案:

答案 0 :(得分:1)

我的第一个想法是将您添加到Label的每个List<Label>添加到您可以从两个布局访问的某个位置...您的视图模型看起来像是合乎逻辑的位置。然后,当您单击按钮时,您可以找到要更改其文本的特定Label并进行更改。您可能需要重新加载列表。

但我认为更好的方法是使用ListView代替StackLayout。然后,您可以为包含一个标签的ItemTemplate设置ListView。然后,您可以设置ObservableCollection<T>个对象以用作ListView.ItemsSource。您可能希望创建一些具有Text属性的自定义对象,或者您想要调用将保存标签文本的属性的任何内容。最好在T中使用ObservableCollection<T>而不是ObservableCollection<string>使用对象,因为对字符串类型的更改不会反映在ListView项中,而是更改为对象的属性(当然假设您使其成为可绑定属性)将反映在绑定到该属性的那些控件中。简而言之,就像(在你的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的{​​{1}}。

如此设置,您可以将Text指定为ListView.ItemsSource dummyLabelContents,然后每当您向ObservableCollection添加项目时,ListView都会自动更新。此外,由于在ObservableCollection中使用具有可绑定文本属性的自定义类型,因此当更改该文本属性时,ObservableCollection中的项目也应相应更新。