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

在Xamarin MVVM中单击按钮更改标签值,xamarin,xamarin.forms,Xamarin,Xamarin.forms,我在Xamarin表单Mvvm中面临一个问题。我有两种不同的布局,比如Layout1和Layout2,它们与一个通用的ViewModel绑定。Layout1包含多个标签,我在xaml.cs文件中使用for循环动态生成这些标签,并使用SetBinding绑定每个标签的sTextProperty。布局2包含一个按钮 现在我想更改单击按钮时特定标签的文本。 布局1.xaml <StackLayout xmlns="http://xamarin.com/schemas/2014/forms" xm

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

现在我想更改单击按钮时特定标签的文本。

布局1.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);
             }

          }

        }
public部分类布局1:StackLayout
{
公共标签dummyLabel;
公共布局1()
{
初始化组件();
对于(int i=0;i<3;i++)
{
dummyLabel=新标签
{
Text=“”,
};
dummyLabel.SetBinding(Label.TextProperty,“PhaseValue”);
parentRowCells.Children.Add(dummyLabel);
var tapGestureRecognizer_1=新的tapGestureRecognizer();
tapGestureRecognizer_1.SetBinding(tapGestureRecognizer.CommandProperty,“LabelClicked”);
tapGestureRecognizer_1.CommandParameter=dummyLabel;
dummyLabel.GestureRecognizers.Add(tapGestureRecognizer_1);
}
}
}
布局2.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";
        });

    }



}
类视图模型
{
公共标签=新标签();
public string textstring=“新建文本字符串”;
i命令_标签点击;
公共ICommand标签已单击
{
得到
{
this.\u labelClicked=this.\u labelClicked??新命令(s=>
{
标签=s作为标签;
label.Text=“new Text”;//这会在单击时更改特定标签的文本,但我需要从另一个布局的按钮单击事件中使用它。
//这里我得到了我点击标签的标签实例。
});
返回此项。_labelClicked;
}
}
公共ICommand按钮ICKEDCommand{protectedset;get;}
公共视图模型()
{
this.ButtonClickCommand=新命令((键)=>
{
//在这里,我想更改单击按钮命令时标签的值。
aa.Text=“这不会改变文本”;
});
}
}

这方面有什么帮助,或者我是否需要遵循其他模式…?

我的第一个想法是将您添加到
列表中的每个
标签添加到可以从两个布局访问的某个位置。。。您的视图模型似乎是一个合乎逻辑的地方。然后,当您单击按钮时,您可以找到要更改其文本的特定
标签
,并对其进行更改。然后,您可能需要重新加载列表

然而,我认为更好的方法是使用
ListView
而不是
StackLayout
。然后,您可以为包含一个标签的
列表视图创建一个
ItemTemplate
。然后可以设置对象的
可观察集合
,用作
列表视图.ItemsSource
。您可能希望创建一些具有文本属性的自定义对象,或者任何您想要调用的属性,这些属性将保存标签的文本。最好在
ObservaleCollection
中为
T
使用对象,而不是使用
ObservaleCollection
,因为对字符串类型的更改不会反映在
ListView
项中,而是对对象属性的更改(当然,假设您将其设置为可绑定属性)将反映在绑定到该属性的控件中。简而言之,类似(在您的ViewModel中):

//类级别变量
可观察收集的Dummylabel内容;
//然后在ViewModel构造函数中或其他地方:
DummyLabelContent=新的ObservableCollection();
自定义类型dummyText;
对于(int i=0;i<3;i++)
{
dummyText=新自定义类型
{
Text=“”,
};
}
添加(dummyText);
您的
CustomType
将只是一个简单的类,只有一个名为
Text
BindableProperty

这样设置,您可以将您的
列表视图。ItemsSource
指定为
DummyLabelContent
ObservableCollection
,然后每当您向
ObservableCollection
添加项目时,列表视图将自动更新。此外,由于在
ObservableCollection
中使用具有可绑定文本属性的自定义类型,因此当该文本属性更改时,
列表视图中的项也应相应更新

// 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);