我在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";
});
}
}
这方面的任何帮助还是我需要遵循其他模式.. ??
答案 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
中的项目也应相应更新。