我有一个带有滑块和标签的简单应用程序。当我移动滑块时,我可以看到setter(Points(被调用并更新值,但当调用PropertyChanged
时,标签不会更新。
我希望它在调用PropertyChanged时调用PointsString
getter。使用调试器,我已经确认正在调用ProperyChanged
,并且正在更新points
的值。为什么在调用点设置器时,绑定到PointsString的标签没有更新?
View.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MyFirstApp.ViewModels"
x:Class="MyFirstApp.Views.DetailPage">
<ContentPage.Content>
<TableView Intent="Form">
<TableRoot>
<TableSection Title="Name">
<EntryCell Label="Name:" />
</TableSection>
<TableSection Title="Rating">
<ViewCell>
<StackLayout Orientation="Horizontal" >
<Label Text="Points:" />
<Label Text="{Binding PointsString}">
<Label.BindingContext>
<vm:DetailsPageViewModel />
</Label.BindingContext>
</Label>
</StackLayout>
</ViewCell>
<ViewCell>
<Grid>
<Slider Maximum="10" Value="{Binding Points , Mode=TwoWay}">
<Slider.BindingContext>
<vm:DetailsPageViewModel/>
</Slider.BindingContext>
</Slider>
</Grid>
</ViewCell>
</TableSection>
</TableRoot>
</TableView>
</ContentPage.Content>
</ContentPage>
模型视图:
using System;
using System.ComponentModel;
class DetailsPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private double points;
public DetailsPageViewModel()
{
points = 4.0;
}
public DetailsPageViewModel(double Points) : this()
{
points = Points;
}
public double Points
{
get { return points; }
set
{
Console.WriteLine(value);
points = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("PointsString"));
}
}
}
public string PointsString
{
// Lazy load from points value
get { return points.ToString(); }
}
}
}
查看XAML时,我怀疑您正在创建新的视图模型,而没有绑定到单个视图模型。
为了在每次声明这个<vm:DetailsPageViewModel />
时提供一些上下文,实际上您正在创建视图模型的一个新实例。
您可以尝试使用"相对"绑定。
本质上你需要改变这一点:
<Label Text="{Binding PointsString}">
<Label.BindingContext>
<vm:DetailsPageViewModel />
</Label.BindingContext>
</Label>
类似的东西:
<Label Text="{Binding Source={RelativeSource AncestorType={x:Type vm:DetailsPageViewModel}}, Path=PointsString}" />
为了证明我的观点,您可以在DetailsPageViewModel
的构造函数中放置一个断点,我预计它会多次命中。
感谢Bijington的回答——我实例化了VM的两个实例。答案是设置页面的Binding上下文并删除特定BindingContext的
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MyFirstApp.ViewModels"
x:Class="MyFirstApp.Views.DetailPage"
>
<ContentPage.BindingContext>
<vm:DetailsPageViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<TableView Intent="Form">
<TableRoot>
<TableSection Title="Name">
<EntryCell Label="Name:" />
</TableSection>
<TableSection Title="Rating">
<ViewCell>
<StackLayout Orientation="Horizontal" >
<Label Text="Points:" />
<Label Text="{Binding PointsString}" />
</StackLayout>
</ViewCell>
<ViewCell>
<Grid>
<Slider Maximum="10" Value="{Binding Points , Mode=TwoWay}" />
</Grid>
</ViewCell>
</TableSection>
</TableRoot>
</TableView>
</ContentPage.Content>
</ContentPage>