Xamarin Forms (MVVM) 中的绑定问题
Problems with Bindings in Xamarin Forms (MVVM)
我在理解 xaml 和 mvvm 时遇到了一些问题。有时有效但其他无效。
ViewModel(实现 INotifyPropertyChanged):
private Class1 firstClass;
public Class1 FirstClass{
get{return firstClass;}
set{firstClass = value; OnPropertyChanged();}
}
private string name;
public string Name{
get{return name;}
set{name = value; OnPropertyChanged();}
}
private string address;
public string Address{
get{return address;}
set{address = value; OnPropertyChanged();}
}
查看:
private ViewModel vm;
在视图构造函数中:
vm = new ViewModel(id);
BindingContext = vm;
OnAppearing(异步):
base.OnAppearing();
await vm.LoadDataAsync();
lAddress.SetBinding(Label.TextProperty, new Binding("Address");
如果我在 xaml 中设置 BindingContext 并将其从
构造函数,它不起作用。
如果我在xaml中的Address标签上设置Binding并从后面的代码中删除它,它不起作用。
如果我尝试使用名称作为页面的标题,它不起作用。
在任何这些情况下,我都没有收到任何类似 'Binding: property not found on BindingContext' 的错误,所以我知道它们正在被发现,但也许它们是空的。
如果我从 Class1 修改一个 属性,它不会出现在页面上。
我可以假设原因是 Class 没有实现
INotifyPropertyChanged?
在 VM 构造函数 (Task.Run) 或 Page.OnAppearing(await vm.LoadData()) 上加载数据更好或更明智吗?
有人可以提供一些指导吗?
编辑:
XAML code (sorry, could not add the code itself)
我认为问题出在这里:
OnAppearing(异步):
base.OnAppearing();
lAddress.SetBinding(Label.TextProperty, new Binding("Address");
await vm.LoadDataAsync();
您必须在方法调用之前设置绑定。
If I set the BindingContext in xaml and remove it from the
constructor, it does not work.
在XAML
中如何设置?您必须向构造函数提供一个 int
参数。所以很可能在 C# 中设置页面的 BindingContext
是有意义的:
class MyPage
{
ViewModel vm;
public MyPage(int id)
{
InitializeComponent();
vm = new ViewModel(id);
BindingContext = vm;
}
}
请注意,您在这里引入了紧耦合,因为您的 Page
知道 ViewModel
具体类型。
If I set the Binding on the Address label in xaml and remove it from
the code behind, it does not work.
下面是带绑定的 Label
在 XAML
中的样子:
<Label Text="{Binding Address}" />
If I try to use Name as the Title of the page, it does not work.
创建页面标题绑定的方法如下:
ContentPage.SetBinding(Page.TitleProperty, nameof(Class1.Name));
请注意,在设置页面BindingContext
后调用。
In any of these cases I am not getting any error like 'Binding:
property not found on BindingContext' so I understand that they are
being found but maybe they are empty.
尝试在vm.LoadDataAsync()
之后打断点,查看ViewModel
的内容。
If I modify a property from Class1, it does not appear on the page.
Can I assume that the reason is that Class does not implement
INotifyPropertyChanged?
越是关注你的问题,越觉得是INotifyPtopertyChanged
的实现问题,能否分享一下相关代码?
Is it better or advisable to LoadData in VM constructor (Task.Run) or
on Page.OnAppearing(await vm.LoadData())?
构造函数应该尽可能简单,永远不要让用户构造函数根据经验执行可能会失败的代码。所以最好引入一个接口,你的 ViewModel
将实现并且应该有方法 OnAppearing()
& OnDisappearing()
,那么你的页面将不知道 ViewModel
具体类型。我想剩下的应该清楚了。
这涉及到相当多的调试(这也是为什么每个 post 一个问题可能更有意义的原因);但这里是:
您的视图模型有一个带有参数的构造函数。如果您在 XAML 中构建,它将使用默认值。基本上,您比较的两段代码并不等同。如果您需要参数,请保留它。
你需要调试这个;确保绑定 属性 对于初学者来说实际上不是空的。
不知道;与您可能需要调试它的地址相同。
您的解释是正确的;我会检查我的数据是否正确加载。
是的。只有在 FirstClass
被重新分配时,您当前的代码才会更新。要捕获该对象内的属性分配 Class1
将需要 INPC(也许这解释了 2 and/or 3)
不确定是否真的重要。
我在理解 xaml 和 mvvm 时遇到了一些问题。有时有效但其他无效。
ViewModel(实现 INotifyPropertyChanged):
private Class1 firstClass;
public Class1 FirstClass{
get{return firstClass;}
set{firstClass = value; OnPropertyChanged();}
}
private string name;
public string Name{
get{return name;}
set{name = value; OnPropertyChanged();}
}
private string address;
public string Address{
get{return address;}
set{address = value; OnPropertyChanged();}
}
查看:
private ViewModel vm;
在视图构造函数中:
vm = new ViewModel(id);
BindingContext = vm;
OnAppearing(异步):
base.OnAppearing();
await vm.LoadDataAsync();
lAddress.SetBinding(Label.TextProperty, new Binding("Address");
如果我在 xaml 中设置 BindingContext 并将其从 构造函数,它不起作用。
如果我在xaml中的Address标签上设置Binding并从后面的代码中删除它,它不起作用。
如果我尝试使用名称作为页面的标题,它不起作用。
在任何这些情况下,我都没有收到任何类似 'Binding: property not found on BindingContext' 的错误,所以我知道它们正在被发现,但也许它们是空的。
如果我从 Class1 修改一个 属性,它不会出现在页面上。 我可以假设原因是 Class 没有实现 INotifyPropertyChanged?
在 VM 构造函数 (Task.Run) 或 Page.OnAppearing(await vm.LoadData()) 上加载数据更好或更明智吗?
有人可以提供一些指导吗?
编辑:
XAML code (sorry, could not add the code itself)
我认为问题出在这里:
OnAppearing(异步):
base.OnAppearing();
lAddress.SetBinding(Label.TextProperty, new Binding("Address");
await vm.LoadDataAsync();
您必须在方法调用之前设置绑定。
If I set the BindingContext in xaml and remove it from the constructor, it does not work.
在XAML
中如何设置?您必须向构造函数提供一个 int
参数。所以很可能在 C# 中设置页面的 BindingContext
是有意义的:
class MyPage
{
ViewModel vm;
public MyPage(int id)
{
InitializeComponent();
vm = new ViewModel(id);
BindingContext = vm;
}
}
请注意,您在这里引入了紧耦合,因为您的 Page
知道 ViewModel
具体类型。
If I set the Binding on the Address label in xaml and remove it from the code behind, it does not work.
下面是带绑定的 Label
在 XAML
中的样子:
<Label Text="{Binding Address}" />
If I try to use Name as the Title of the page, it does not work.
创建页面标题绑定的方法如下:
ContentPage.SetBinding(Page.TitleProperty, nameof(Class1.Name));
请注意,在设置页面BindingContext
后调用。
In any of these cases I am not getting any error like 'Binding: property not found on BindingContext' so I understand that they are being found but maybe they are empty.
尝试在vm.LoadDataAsync()
之后打断点,查看ViewModel
的内容。
If I modify a property from Class1, it does not appear on the page. Can I assume that the reason is that Class does not implement INotifyPropertyChanged?
越是关注你的问题,越觉得是INotifyPtopertyChanged
的实现问题,能否分享一下相关代码?
Is it better or advisable to LoadData in VM constructor (Task.Run) or on Page.OnAppearing(await vm.LoadData())?
构造函数应该尽可能简单,永远不要让用户构造函数根据经验执行可能会失败的代码。所以最好引入一个接口,你的 ViewModel
将实现并且应该有方法 OnAppearing()
& OnDisappearing()
,那么你的页面将不知道 ViewModel
具体类型。我想剩下的应该清楚了。
这涉及到相当多的调试(这也是为什么每个 post 一个问题可能更有意义的原因);但这里是:
您的视图模型有一个带有参数的构造函数。如果您在 XAML 中构建,它将使用默认值。基本上,您比较的两段代码并不等同。如果您需要参数,请保留它。
你需要调试这个;确保绑定 属性 对于初学者来说实际上不是空的。
不知道;与您可能需要调试它的地址相同。
您的解释是正确的;我会检查我的数据是否正确加载。
是的。只有在
FirstClass
被重新分配时,您当前的代码才会更新。要捕获该对象内的属性分配Class1
将需要 INPC(也许这解释了 2 and/or 3)不确定是否真的重要。