Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 加载时激发的Xamarin TimePicker propertychanged事件_Android_Xamarin_Xamarin.forms_Timepicker_Propertychanged - Fatal编程技术网

Android 加载时激发的Xamarin TimePicker propertychanged事件

Android 加载时激发的Xamarin TimePicker propertychanged事件,android,xamarin,xamarin.forms,timepicker,propertychanged,Android,Xamarin,Xamarin.forms,Timepicker,Propertychanged,我正在为android开发一个Xamarin应用程序,使用Xamarin表单创建我的布局。我遇到了一个问题,我的时间选择器在加载我的查看单元时开火 我要做的是创建一个列表视图,然后将项目模板设置为我的自定义视图单元格模板。在我的视图单元格模板中,我正在创建一个时间选择器并将PropertyChanged事件绑定到它。我还使用从数据库检索的信息设置TimePicker.Time属性。此时似乎发生的情况是,将为列表视图中显示的每个项目触发MyPropertyChanged事件。这会导致不需要的多个数

我正在为android开发一个Xamarin应用程序,使用Xamarin表单创建我的布局。我遇到了一个问题,我的时间选择器在加载我的查看单元时开火

我要做的是创建一个列表视图,然后将项目模板设置为我的自定义视图单元格模板。在我的视图单元格模板中,我正在创建一个时间选择器并将PropertyChanged事件绑定到它。我还使用从数据库检索的信息设置TimePicker.Time属性。此时似乎发生的情况是,将为列表视图中显示的每个项目触发MyPropertyChanged事件。这会导致不需要的多个数据库调用

是否有方法停止调用PropertyChanged事件,直到属性实际发生更改

我的代码如下

public class MyCell : ViewCell
{
private readonly TimePicker _myTimePicker;
public MyCell()
{
   _myTimePicker = new TimePicker()
        {
            HorizontalOptions = LayoutOptions.EndAndExpand
        };

        _myTimePicker.SetBinding(TimePicker.TimeProperty, "StartTime");
        _myTimePicker.PropertyChanged += MyTimePicker_PropertyChanged;

        var viewLayout = new StackLayout()
        {
            HorizontalOptions = LayoutOptions.StartAndExpand,
            Orientation = StackOrientation.Horizontal,
            Padding = new Thickness(20),
            Children = { _myTimePicker }
        };
        View = viewLayout;
}

private void MyTimePicker_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == TimePicker.TimeProperty.PropertyName && _myTimePicker.Time != TimeSpan.MinValue)
        {
            var dataAccess = new DataAccessLayer();
            dataAccess.Update(myTimePicker.Time);
        }
    }
}
我不知道为什么propertychanged事件被多次触发,以及在我真正选择时间之前如何停止触发。任何帮助都将不胜感激

下面是用于显示列表视图的表单的代码。我所有的xaml都是在代码中定义的。”MyCell'使用从“_dataAccess.GetTimes()”返回的值

_dataAcess.GetTimes()的返回类型是TaskTime的列表。TaskTime模型如下所示

public class TaskTime
{
    public int Id { get; set; }
    public string Task { get; set; }
    public TimeSpan StartTime { get; set; }
}

使用聚焦和非聚焦事件的更简单解决方案是:

public class CustomTimePicker : TimePicker
{
    public event EventHandler TimeChanged;

    private TimeSpan StartValue { get; set; }

    public CustomTimePicker ()
    {
        this.Focused += OnFoused;
        this.Unfocused += OnUnfocused;
    }

    private void OnFoused(object sender, FocusEventArgs e)
    {
        StartValue = this.Time;
    }

    private void OnUnfocused(object sender, FocusEventArgs e)
    {
        if (StartValue != this.Time)
        {
            TimeChanged?.Invoke(this, e);
        }
    }
}

我猜你发布的代码在你的页面上?还可以发布xaml并编写如何绑定到listview的代码吗?特别是在指定ItemSource和ItemBindingTemplate的位置。不清楚您是在xaml中还是在代码中执行它。然后,我可以尝试重新生成我最初发布的代码,它位于我的自定义单元格中,用于列表视图项模板。我已根据您要求的信息对原始问题进行了编辑。谢谢。迈塞尔是从什么东西衍生出来的吗?我看到视图=视图布局;但是在迈塞尔没有风景。还有什么_dataAccess.GetTimes();返回?listView中没有定义绑定。你能把整个源代码放在某个地方,这样我可以更快地帮助你吗?上面有更新和问题。我不确定我可以把代码放在哪里让你看一看。Dropbox或Github这是有意义的。你知道有什么方法可以阻止这一切吗?是的。不订阅属性更改,但您将不知道何时选择时间。我确实需要知道何时选择时间,因为需要使用所选时间更新数据库。我会和其他东西玩一玩,看看我是否能绕过它。我已经设法解决了这个问题,在我把它作为答案发布之前,你可以告诉我这是否是一个好的解决方案。我已经创建了一个新的时间选择器,并将“StartTime”的值设置为它(与我使用_myTimePicker所做的相同)。然后添加到if语句并比较我的两个计时器的值。当我修改myTimePicker时,值是不同的,因此属性更改事件中的更新代码将运行。在这里,我现在还将新的TimePicker设置为_myTimePicker的新值。听起来怎么样?如果你想玩的话,你可以用PropertyChanged事件订阅和取消订阅来玩非焦点事件。
class MyCell : ViewCell
{
    private readonly TimePicker _myTimePicker;
    public MyCell()
    {
        _myTimePicker = new TimePicker()
        {
            HorizontalOptions = LayoutOptions.EndAndExpand
        };

        _myTimePicker.SetBinding(TimePicker.TimeProperty, "StartTime");
        _myTimePicker.PropertyChanged += MyTimePicker_PropertyChanged;
        _myTimePicker.Focused += _myTimePicker_Focused;

        var viewLayout = new StackLayout()
        {
            HorizontalOptions = LayoutOptions.StartAndExpand,
            Orientation = StackOrientation.Horizontal,
            Padding = new Thickness(20),
            Children = { _myTimePicker }
        };
        View = viewLayout;
    }

    bool myTimePickerSelected;
    private void _myTimePicker_Focused(object sender, FocusEventArgs e)
    {
        myTimePickerSelected = true;
    }

    private void MyTimePicker_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {

        if (e.PropertyName == TimePicker.TimeProperty.PropertyName && myTimePickerSelected)
        {
            //var dataAccess = new DataAccessLayer();
            //dataAccess.Update(myTimePicker.Time);
        }
    }
}
public class CustomTimePicker : TimePicker
{
    public event EventHandler TimeChanged;

    private TimeSpan StartValue { get; set; }

    public CustomTimePicker ()
    {
        this.Focused += OnFoused;
        this.Unfocused += OnUnfocused;
    }

    private void OnFoused(object sender, FocusEventArgs e)
    {
        StartValue = this.Time;
    }

    private void OnUnfocused(object sender, FocusEventArgs e)
    {
        if (StartValue != this.Time)
        {
            TimeChanged?.Invoke(this, e);
        }
    }
}