我想用 xamarin 形式制作一个简单的秒表应用程序。
这是界面:
<?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:local="clr-namespace:testvb"
x:Class="testvb.MainPage">
<StackLayout>
<Label Text="{Binding LabelText}">
<Label.BindingContext>
<local:GetDuration/>
</Label.BindingContext>
<Label.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding TapCommand}">
</TapGestureRecognizer>
</Label.GestureRecognizers>
</Label>
<Label Text="{Binding SWDuration}">
<Label.BindingContext>
<local:GetDuration/>
</Label.BindingContext>
</Label>
<Label Text="{Binding StartTimeText}">
<Label.BindingContext>
<local:GetDuration/>
</Label.BindingContext>
</Label>
</StackLayout>
</ContentPage>
和 c# 类:
namespace testvb
{
class GetDuration : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
static string labeltext = "START";
static string starttimetext = "Timer hasn't been started";
ICommand tapCommand;
static Stopwatch hstopwatch = new Stopwatch();
string swduration;
public GetDuration()
{
tapCommand = new Command(OnTapped);
this.SWDuration = hstopwatch.Elapsed.ToString();
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
this.SWDuration = hstopwatch.Elapsed.ToString();
return true;
});
}
public ICommand TapCommand
{
get
{
return tapCommand;
}
}
void OnTapped (object s)
{
if(LabelText == "START")
{
LabelText = "STOP";
StartTimeText = DateTime.Now.ToString();
hstopwatch.Restart();
}
else
{
LabelText = "START";
StartTimeText = "Timer has been stopped";
hstopwatch.Stop();
hstopwatch.Reset();
}
}
public string LabelText
{
get
{
return labeltext;
}
set
{
if(labeltext != value)
{
labeltext = value;
if(PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs("LabelText"));
}
}
}
}
public string SWDuration
{
get
{
return swduration;
}
set
{
if(swduration!=value)
{
swduration = value;
if(PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs("SWDuration"));
}
}
}
}
public string StartTimeText
{
get
{
return starttimetext;
}
set
{
if (starttimetext != value)
{
starttimetext = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("StartTimeText"));
}
}
}
}
}
}
从界面开始,我有一个标签(单击时开始和停止之间的切换),一个显示持续时间的标签,以及一个显示秒表启动时间的标签。
xamarin android 模拟器上的输出:_
我不明白为什么它不能用于最后一个标签,因为主体与第一个标签(开始/停止)相同。如果有人能指出我误解的地方或我在代码中做错的部分,我将非常感谢。
谢谢你。
通过设置BindingContext
与
<Label.BindingContext>
<local:GetDuration/>
</Label.BindingContext>
分别为每个标签Label
创建一个新实例GetDuration
。因此,您正在调用的实例TapCommand
将与附加到您的标签的实例不同。
通过将您的 XAML 更改为
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:stopwatch"
x:Class="stopwatch.MainPage">
<ContentPage.BindingContext>
<local:GetDuration></local:GetDuration>
</ContentPage.BindingContext>
<StackLayout>
<Label Text="{Binding LabelText}">
<Label.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding TapCommand}">
</TapGestureRecognizer>
</Label.GestureRecognizers>
</Label>
<Label Text="{Binding SWDuration}" />
<Label Text="{Binding StartTimeText}" />
</StackLayout>
</ContentPage>
您正在创建单个GetDuration
作为页面的绑定上下文。除非另有明确设置,否则BindingContext
将传递给页面的子级,因此无需为每个标签设置它(不管它无论如何都不起作用的事实)。
补充说明
事件调用者
您正在从每个属性手动引发事件。创建一个为您执行此操作的事件调用器将为您节省一些行并使您更加坚持 DRY
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
由于该CallerMemberName
属性,调用属性的名称将自动传递(毕竟它是语法糖,编译器会为您做魔术)。属性会变成
public string StartTimeText
{
get
{
return starttimetext;
}
set
{
if (starttimetext != value)
{
starttimetext = value;
this.OnPropertyChanged();
}
}
}
用于决定的 LabelText
void OnTapped(object s)
{
if (LabelText == "START")
{
LabelText = "STOP";
StartTimeText = DateTime.Now.ToString();
hstopwatch.Restart();
}
else
{
LabelText = "START";
StartTimeText = "Timer has been stopped";
hstopwatch.Stop();
hstopwatch.Reset();
}
}
这可能是一个品味问题,但我不会让决定是开始还是停止时间取决于 的值LabelText
,而是取决于内部的bool
或enum
。你做事的方式,你内部和外部的行为。毕竟它是面向对象的,你应该利用封装。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句