C# 更改值后,ListView中的时间选择器再次弹出时间选择界面
我有一个视图,其中包含一个带有暂停列表的模型。每一个都有一个开始和结束 在我的页面中,我使用一个ListView,将这些暂停绑定到它。 因此,在每个ViewCell中都有两个时间选择器,一个用于开始时间,一个用于结束时间 如果我更改起始值,一切正常,但是如果我更改结束值,则会发生奇怪的事情:输入值后,输入弹出窗口关闭。然后,它再次打开,显示结束时间的值,然后出现另一个弹出窗口,这次显示开始时间的值 在使用各种布局、添加或删除NotifyPropertyChanged事件之后,我仍然不知道为什么会发生这种情况或为什么会发生这种情况。 它有点像一个xamarin bug,看起来像是牢房里所有时间选择器的焦点和非焦点事件都被触发了 编辑:看起来它真的是一个xamarin bug: PauseModel.cs(共享项目):C# 更改值后,ListView中的时间选择器再次弹出时间选择界面,c#,xamarin,mvvm,xamarin.forms,C#,Xamarin,Mvvm,Xamarin.forms,我有一个视图,其中包含一个带有暂停列表的模型。每一个都有一个开始和结束 在我的页面中,我使用一个ListView,将这些暂停绑定到它。 因此,在每个ViewCell中都有两个时间选择器,一个用于开始时间,一个用于结束时间 如果我更改起始值,一切正常,但是如果我更改结束值,则会发生奇怪的事情:输入值后,输入弹出窗口关闭。然后,它再次打开,显示结束时间的值,然后出现另一个弹出窗口,这次显示开始时间的值 在使用各种布局、添加或删除NotifyPropertyChanged事件之后,我仍然不知道为什么会
public class PauseModel : INotifyPropertyChanged
{
public PauseModel()
{
}
public PauseModel(DateTimeOffset start, DateTimeOffset end)
{
PauseStart = start;
PauseEnd = end;
}
public DateTimeOffset PauseStart
{
get { return pauseStart; }
set { pauseStart = value; }
}
private DateTimeOffset pauseStart;
public DateTimeOffset PauseEnd
{
get { return pauseEnd; }
set { pauseEnd = value; }
}
private DateTimeOffset pauseEnd;
public TimeSpan StartTime
{
get { return PauseStart.TimeOfDay; }
set { PauseStart = PauseStart.Date + value; }
}
public TimeSpan EndTime
{
get { return PauseEnd.TimeOfDay; }
set { PauseEnd = PauseEnd.Date + value; }
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class PauseScreenModel
{
public PauseScreenModel()
{
}
public PauseScreenModel(bool prefill = false)
{
if (prefill == true)
{
DateTimeOffset todayDate = new DateTimeOffset(DateTimeOffset.Now.Year, DateTimeOffset.Now.Month, DateTimeOffset.Now.Day, 0, 0, 0, DateTimeOffset.Now.Offset);
Pauses = new ObservableCollection<PauseModel>()
{
new PauseModel(todayDate + new TimeSpan(11,0,0), todayDate + new TimeSpan(11,10,0)),
new PauseModel(todayDate + new TimeSpan(13,15,0), todayDate + new TimeSpan(13,45,0)),
new PauseModel(todayDate + new TimeSpan(16,40,0), todayDate + new TimeSpan(16,50,0))
};
}
}
public ObservableCollection<PauseModel> Pauses
{
get;set;
}
}
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TimePickerListTest"
x:Class="TimePickerListTest.PauseViewPage">
<ListView ItemsSource="{Binding Pauses}" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Height="80">
<Grid Margin="0" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="Start Time" Grid.Row="0" Grid.Column="0" />
<Label Text="End Time" Grid.Row="0" Grid.Column="1" />
<TimePicker Time="{Binding StartTime}" Grid.Row="1" Grid.Column="0" />
<TimePicker Time="{Binding EndTime}" Grid.Row="1" Grid.Column="1" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
注意,还没有任何真正的PropertyChanged实现,我删除了它,以确保PropertyChanged事件不会导致错误行为。StartTime和EndTime是“适配器属性”,允许将值绑定到时间选择器元素。我还尝试使用专用的TimeSpan属性而不是“适配器”,这也没有改变选择器的错误行为
PauseScreenModel.cs(共享项目):
public class PauseModel : INotifyPropertyChanged
{
public PauseModel()
{
}
public PauseModel(DateTimeOffset start, DateTimeOffset end)
{
PauseStart = start;
PauseEnd = end;
}
public DateTimeOffset PauseStart
{
get { return pauseStart; }
set { pauseStart = value; }
}
private DateTimeOffset pauseStart;
public DateTimeOffset PauseEnd
{
get { return pauseEnd; }
set { pauseEnd = value; }
}
private DateTimeOffset pauseEnd;
public TimeSpan StartTime
{
get { return PauseStart.TimeOfDay; }
set { PauseStart = PauseStart.Date + value; }
}
public TimeSpan EndTime
{
get { return PauseEnd.TimeOfDay; }
set { PauseEnd = PauseEnd.Date + value; }
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class PauseScreenModel
{
public PauseScreenModel()
{
}
public PauseScreenModel(bool prefill = false)
{
if (prefill == true)
{
DateTimeOffset todayDate = new DateTimeOffset(DateTimeOffset.Now.Year, DateTimeOffset.Now.Month, DateTimeOffset.Now.Day, 0, 0, 0, DateTimeOffset.Now.Offset);
Pauses = new ObservableCollection<PauseModel>()
{
new PauseModel(todayDate + new TimeSpan(11,0,0), todayDate + new TimeSpan(11,10,0)),
new PauseModel(todayDate + new TimeSpan(13,15,0), todayDate + new TimeSpan(13,45,0)),
new PauseModel(todayDate + new TimeSpan(16,40,0), todayDate + new TimeSpan(16,50,0))
};
}
}
public ObservableCollection<PauseModel> Pauses
{
get;set;
}
}
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TimePickerListTest"
x:Class="TimePickerListTest.PauseViewPage">
<ListView ItemsSource="{Binding Pauses}" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Height="80">
<Grid Margin="0" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="Start Time" Grid.Row="0" Grid.Column="0" />
<Label Text="End Time" Grid.Row="0" Grid.Column="1" />
<TimePicker Time="{Binding StartTime}" Grid.Row="1" Grid.Column="0" />
<TimePicker Time="{Binding EndTime}" Grid.Row="1" Grid.Column="1" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
因此,任何能为我指明正确方向的帮助都将不胜感激
编辑:该问题发生在使用Xamarin Forms 3.4.0.1008975运行Android 8.1的LG K8上,以及运行Android 6.0的模拟器上,但是,在Android 6.0.1的三星Galaxy Note 4上,选择器的行为与预期一致。您能提供更多详细信息吗?例如xamarin.forms和测试设备的版本?我使用您的代码,效果很好。在主要问题中添加了设备和xamarin forms版本。你用的是哪款手机?我用的是运行安卓8.1和iPhone的Nexus。我建议你可以创建一个新项目,在页面上添加两个时间选择器,而不使用listview。因为我不认为这与你的代码有任何关系。在我最初的应用程序中,我偶然发现了这个问题,除了列表视图中的时间选择器之外,我还有两个额外的时间选择器。这些工作非常好。正如我在第一个问题中补充的那样,一些设备具有这种不稳定的行为,而另一些设备则没有。然而,在xamarin的bugtracker中已经有一张正是这方面的罚单。