Android 加载时激发的Xamarin TimePicker propertychanged事件
我正在为android开发一个Xamarin应用程序,使用Xamarin表单创建我的布局。我遇到了一个问题,我的时间选择器在加载我的查看单元时开火 我要做的是创建一个列表视图,然后将项目模板设置为我的自定义视图单元格模板。在我的视图单元格模板中,我正在创建一个时间选择器并将PropertyChanged事件绑定到它。我还使用从数据库检索的信息设置TimePicker.Time属性。此时似乎发生的情况是,将为列表视图中显示的每个项目触发MyPropertyChanged事件。这会导致不需要的多个数据库调用 是否有方法停止调用PropertyChanged事件,直到属性实际发生更改 我的代码如下Android 加载时激发的Xamarin TimePicker propertychanged事件,android,xamarin,xamarin.forms,timepicker,propertychanged,Android,Xamarin,Xamarin.forms,Timepicker,Propertychanged,我正在为android开发一个Xamarin应用程序,使用Xamarin表单创建我的布局。我遇到了一个问题,我的时间选择器在加载我的查看单元时开火 我要做的是创建一个列表视图,然后将项目模板设置为我的自定义视图单元格模板。在我的视图单元格模板中,我正在创建一个时间选择器并将PropertyChanged事件绑定到它。我还使用从数据库检索的信息设置TimePicker.Time属性。此时似乎发生的情况是,将为列表视图中显示的每个项目触发MyPropertyChanged事件。这会导致不需要的多个数
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);
}
}
}