Xamarin Forms:如何将两个视图模型中的数据正确绑定到单个视图?
Xamarin Forms: How can i correctly bind data from two view models to a single view?
这是用于测试目的的短代码。问题是 UI 没有显示与 ViewModelB 绑定的标签中的文本。在调试中,当我将鼠标悬停在 xaml 中的标签文本上时,我看到正确的绑定数据在那里,但 UI 根本不会显示。使用 ViewModelA 没有问题。
在XAML中:
<StackLayout>
<StackLayout>
<StackLayout.BindingContext>
<testbinding:ViewModelA/>
</StackLayout.BindingContext>
<Button Command ="{Binding Get}"/>
</StackLayout>
<StackLayout>
<StackLayout.BindingContext>
<testbinding:ViewModelB/>
</StackLayout.BindingContext>
<Label Text="{Binding Metadata}"/>
</StackLayout>
ViewModelA:其中 BaseViewModel 是一个 INotifyPropertyChanged 接口
public ViewModelA:BaseViewModel
{
public ViewModelA()
{
Get = new Command(SendText);
vmB = new ViewModelB();
}
ViewModelB vmB;
public ICommand Get { get; }
private void SendText()
{
string data = "someText";
vmB.GetMetadata(data);
}
}
ViewModelB 是这样的:
class ViewModelB:BaseViewModel
{
private string _metadata = string.Empty;
public string Metadata
{
get { return _metadata; }
set
{
_metadata = value;
OnPropertyChanged();
}
}
GetMetadata()
{
Metadata = "Some text";
}
}
在 ViewModelA 中有更多我需要的属性,而在 ViewModelB 中只有一个 属性 从函数获取数据。我可以从它们两个中只制作一个 ViewModel,效果很好,但我试图让它们更小、更有条理。我已经尝试了很多场景,并且真的很沮丧。
感谢您的帮助。
在您的 xaml 文件的第二个 StackLayout 中,您没有将它的 BindingContext 属性 绑定到 ViewModelA 的 ViewModelB 实例,而是创建了一个新实例。
这是适合您的有效解决方案:
public class ViewModelA : BaseViewModel
{
public ViewModelB ViewModelB { get; }
public ICommand GetMetadataCommand { get; }
public ViewModelA()
{
ViewModelB = new ViewModelB();
GetMetadataCommand = new Command((_) => GetMetadata());
}
private void GetMetadata()
{
string data = "someText";
ViewModelB.GetMetadata(data);
}
}
public class ViewModelB : BaseViewModel
{
private string _metadata;
public string Metadata
{
get { return _metadata; }
set
{
_metadata = value;
OnPropertyChanged();
}
}
public void GetMetadata(string data)
{
Metadata = data;
}
}
XAMl:
<StackLayout>
<StackLayout x:Name="StackLayout1">
<StackLayout.BindingContext>
<local:ViewModelA />
</StackLayout.BindingContext>
<Button Command ="{Binding GetMetadataCommand}"/>
</StackLayout>
<StackLayout BindingContext="{Binding Source={x:Reference StackLayout1}, Path=BindingContext.ViewModelB}">
<Label Text="{Binding Metadata}" />
</StackLayout>
</StackLayout>
这是用于测试目的的短代码。问题是 UI 没有显示与 ViewModelB 绑定的标签中的文本。在调试中,当我将鼠标悬停在 xaml 中的标签文本上时,我看到正确的绑定数据在那里,但 UI 根本不会显示。使用 ViewModelA 没有问题。
在XAML中:
<StackLayout>
<StackLayout>
<StackLayout.BindingContext>
<testbinding:ViewModelA/>
</StackLayout.BindingContext>
<Button Command ="{Binding Get}"/>
</StackLayout>
<StackLayout>
<StackLayout.BindingContext>
<testbinding:ViewModelB/>
</StackLayout.BindingContext>
<Label Text="{Binding Metadata}"/>
</StackLayout>
ViewModelA:其中 BaseViewModel 是一个 INotifyPropertyChanged 接口
public ViewModelA:BaseViewModel
{
public ViewModelA()
{
Get = new Command(SendText);
vmB = new ViewModelB();
}
ViewModelB vmB;
public ICommand Get { get; }
private void SendText()
{
string data = "someText";
vmB.GetMetadata(data);
}
}
ViewModelB 是这样的:
class ViewModelB:BaseViewModel
{
private string _metadata = string.Empty;
public string Metadata
{
get { return _metadata; }
set
{
_metadata = value;
OnPropertyChanged();
}
}
GetMetadata()
{
Metadata = "Some text";
}
}
在 ViewModelA 中有更多我需要的属性,而在 ViewModelB 中只有一个 属性 从函数获取数据。我可以从它们两个中只制作一个 ViewModel,效果很好,但我试图让它们更小、更有条理。我已经尝试了很多场景,并且真的很沮丧。 感谢您的帮助。
在您的 xaml 文件的第二个 StackLayout 中,您没有将它的 BindingContext 属性 绑定到 ViewModelA 的 ViewModelB 实例,而是创建了一个新实例。
这是适合您的有效解决方案:
public class ViewModelA : BaseViewModel
{
public ViewModelB ViewModelB { get; }
public ICommand GetMetadataCommand { get; }
public ViewModelA()
{
ViewModelB = new ViewModelB();
GetMetadataCommand = new Command((_) => GetMetadata());
}
private void GetMetadata()
{
string data = "someText";
ViewModelB.GetMetadata(data);
}
}
public class ViewModelB : BaseViewModel
{
private string _metadata;
public string Metadata
{
get { return _metadata; }
set
{
_metadata = value;
OnPropertyChanged();
}
}
public void GetMetadata(string data)
{
Metadata = data;
}
}
XAMl:
<StackLayout>
<StackLayout x:Name="StackLayout1">
<StackLayout.BindingContext>
<local:ViewModelA />
</StackLayout.BindingContext>
<Button Command ="{Binding GetMetadataCommand}"/>
</StackLayout>
<StackLayout BindingContext="{Binding Source={x:Reference StackLayout1}, Path=BindingContext.ViewModelB}">
<Label Text="{Binding Metadata}" />
</StackLayout>
</StackLayout>