C# 更改值后,ListView中的时间选择器再次弹出时间选择界面

C# 更改值后,ListView中的时间选择器再次弹出时间选择界面,c#,xamarin,mvvm,xamarin.forms,C#,Xamarin,Mvvm,Xamarin.forms,我有一个视图,其中包含一个带有暂停列表的模型。每一个都有一个开始和结束 在我的页面中,我使用一个ListView,将这些暂停绑定到它。 因此,在每个ViewCell中都有两个时间选择器,一个用于开始时间,一个用于结束时间 如果我更改起始值,一切正常,但是如果我更改结束值,则会发生奇怪的事情:输入值后,输入弹出窗口关闭。然后,它再次打开,显示结束时间的值,然后出现另一个弹出窗口,这次显示开始时间的值 在使用各种布局、添加或删除NotifyPropertyChanged事件之后,我仍然不知道为什么会

我有一个视图,其中包含一个带有暂停列表的模型。每一个都有一个开始和结束

在我的页面中,我使用一个ListView,将这些暂停绑定到它。 因此,在每个ViewCell中都有两个时间选择器,一个用于开始时间,一个用于结束时间

如果我更改起始值,一切正常,但是如果我更改结束值,则会发生奇怪的事情:输入值后,输入弹出窗口关闭。然后,它再次打开,显示结束时间的值,然后出现另一个弹出窗口,这次显示开始时间的值

在使用各种布局、添加或删除NotifyPropertyChanged事件之后,我仍然不知道为什么会发生这种情况或为什么会发生这种情况。 它有点像一个xamarin bug,看起来像是牢房里所有时间选择器的焦点和非焦点事件都被触发了

编辑:看起来它真的是一个xamarin bug:

PauseModel.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>
注意,还没有任何真正的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中已经有一张正是这方面的罚单。