2016-11-12 16 views
1

我正在开发一个Xamarin应用程序,用于使用Xamarin表单创建我的布局的android。我遇到了一个问题,我的时间选择器触发了我的查看单元格的加载。Xamarin TimePicker属性加载时触发的事件

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

有没有办法阻止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()'返回的值。

public class TimeDetails : ContentPage 
{ 
    private ListView _listView; 
    private readonly DataAccessLayer _dataAccess = new DataAccessLayer(); 

    protected override void OnAppearing() 
    { 
     _listView = new ListView 
     { 
      RowHeight = 80, 
      SeparatorColor = Color.Blue, 
      SeparatorVisibility = SeparatorVisibility.Default 
     }; 

     _listView.ItemsSource = _dataAccess.GetTimes(); 
     _listView.ItemTemplate = new DataTemplate(typeof(MyCell)); 
     _listView.ItemSelected += ListView_ItemSelected; 

     Content = new StackLayout 
     { 
      VerticalOptions = LayoutOptions.FillAndExpand, 
      Children = { _listView } 
     }; 
    } 
} 

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

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

我认为这个代码,你贴在你的网页?你也可以发布你的xaml和代码如何绑定到列表视图?特别是你分配你的ItemSource和ItemBindingTemplate的地方。目前尚不清楚你是在xaml还是在代码的某处。然后我可以尝试重现 –

+0

我最初发布的代码位于我的定制单元格中,该单元格用于列表视图项目模板中。我已根据您提供的信息对原始问题进行了编辑。谢谢。 – Usman26

+0

MyCell是从什么派生出来的?我看到View = viewLayout;但MyCell中没有视图。还有什么_dataAccess.GetTimes();回报?没有在listView中定义的绑定。你能把整个源代码放在什么地方,这样我可以更快地帮助你吗? –

回答

1
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); 
     } 
    } 
} 
+0

这确实有道理。你知道这可以被阻止吗? – Usman26

+0

是的。不要订阅属性更改,但不知道什么时候选择了时间 –

+0

我确实需要知道何时选择时间,因为需要使用所选时间更新数据库。我会和其他玩家一起玩,看看我能否解决它。 – Usman26