2017-04-11 17 views
0

我想运行时间让我们说5个城市,就像列表视图和时钟(本地时间)的每个单元格中除城市名称外的所有城市一样。 (屏幕截图如下)如何在Xamarin表单中分别运行ListView的所有项目中的StartTimer

我正在使用该城市的偏移值获取城市的当地时间。

而对于时钟移动,我使用了StartTimer,以便时间每秒都会改变。

目前我在那里得到offsetValue为零,因此所有城市的UTC时间都相同。

我希望当地时间显示在城市名称旁边的所有城市,时钟必须每隔一秒移动一次。

任何帮助将不胜感激。 在此先感谢。

Sample screenshot of cities with respective clocks

List<OffsetItems> items = new List<OffsetItems>(); 
     items.Add(new OffsetItems() { CityName = "Hyderabad", Offset = 5.5 }); 
     items.Add(new OffsetItems() { CityName = "London", Offset = 1 }); 
     items.Add(new OffsetItems() { CityName = "Tokyo", Offset = 9 }); 
     items.Add(new OffsetItems() { CityName = "New York", Offset = -5 }); 
     items.Add(new OffsetItems() { CityName = "Dubai", Offset = 4 }); 


     ListView lv = new ListView 
     { 
      SeparatorVisibility = SeparatorVisibility.None, 
      ItemsSource = items, 

      ItemTemplate = new DataTemplate(() => 
      { 

       Label cityL = new Label() 
       { 
        TextColor = Color.Black, 
        HorizontalTextAlignment = TextAlignment.Start, 
        FontSize = Device.GetNamedSize(NamedSize.Small, new Label()) 
       }; 
       Label timeL = new Label() 
       { 
        TextColor = Color.Black, 
        HorizontalTextAlignment = TextAlignment.Center, 
        FontSize = Device.GetNamedSize(NamedSize.Small, new Label()) 
       }; 
       cityL.SetBinding<OffsetItems>(Label.TextProperty, indexer => indexer.CityName); 

       Label ll = new Label(); 
       Device.StartTimer(TimeSpan.FromSeconds(1),() => { 

        ll.SetBinding<OffsetItems>(Label.TextProperty, indexer => indexer.Offset); 
        double offsetValue = Convert.ToDouble(ll.Text); 

        timeL.Text = DateTime.UtcNow.AddHours(offsetValue).ToString("hh:mm:ss tt, ddd dd-MMM-yyyy"); 
        return true; 
       }); 

       return new ViewCell 
       { 
        View = new StackLayout 
        { 
         Orientation = StackOrientation.Horizontal, 
         Children = 
          { 
          cityL, 
          timeL 
         } 
        } 
       }; 
      }) 
     }; 

     Content = new StackLayout 
     { 
      Children = { 
       lv 
      } 
     }; 

回答

0

我已经添加了Alessandro提到的代码,这就是它应该如何完成的。

class OffsetItems : INotifyPropertyChanged 
    { 
     private double _offset; 
     private string _time; 
     private string _cityName; 

     public string CityName 
     { 
      get { return _cityName; } 
      internal set 
      { 
       _cityName = value; 
       OnPropertyChanged("CityName"); 
      } 
     } 

     public string Time 
     { 
      get { return _time; } 
      internal set 
      { 
       _time = value; 
       OnPropertyChanged("Time"); 
      } 
     } 

     public double Offset 
     { 
      get { return _offset; } 
      internal set 
      { 
       _offset = value; 
       OnPropertyChanged("Offset"); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public partial class MainPage : ContentPage 
    { 
     ObservableCollection<OffsetItems> Items = new ObservableCollection<OffsetItems>(); 

     public MainPage() 
     { 
      InitializeComponent(); 

      Items.Add(new OffsetItems() { CityName = "Hyderabad", Offset = 5.5 }); 
      Items.Add(new OffsetItems() { CityName = "London", Offset = 1 }); 
      Items.Add(new OffsetItems() { CityName = "Tokyo", Offset = 9 }); 
      Items.Add(new OffsetItems() { CityName = "New York", Offset = -5 }); 
      Items.Add(new OffsetItems() { CityName = "Dubai", Offset = 4 }); 

      var lv = new ListView 
      { 
       ItemsSource = Items, 
       SeparatorVisibility = SeparatorVisibility.None, 
       ItemTemplate = new DataTemplate(() => 
       { 

        Label cityL = new Label() 
        { 
         TextColor = Color.Black, 
         HorizontalTextAlignment = TextAlignment.Start, 
         FontSize = Device.GetNamedSize(NamedSize.Small, new Label()) 
        }; 
        Label timeL = new Label() 
        { 
         TextColor = Color.Black, 
         HorizontalTextAlignment = TextAlignment.Center, 
         FontSize = Device.GetNamedSize(NamedSize.Small, new Label()) 
        }; 
        cityL.SetBinding<OffsetItems>(Label.TextProperty, indexer => indexer.CityName); 
        timeL.SetBinding<OffsetItems>(Label.TextProperty, indexer => indexer.Time, BindingMode.OneWay); 

        Label ll = new Label(); 

        return new ViewCell 
        { 
         View = new StackLayout 
         { 
          Orientation = StackOrientation.Horizontal, 
          Children = 
          { 
           cityL, 
           timeL 
          } 
         } 
        }; 
       }) 
      }; 

      Content = new StackLayout 
      { 
       Children = { 
        lv 
       } 
      }; 
     } 

     protected override void OnAppearing() 
     { 
      base.OnAppearing(); 
      Device.StartTimer(TimeSpan.FromSeconds(1),() => 
      { 
       Items.ForEach(row => row.Time = DateTime.UtcNow.AddHours(row.Offset) 
        .ToString("hh:mm:ss tt, ddd dd-MMM-yyyy")); 
       return true; 
      }); 
     } 
    } 

* Foreach是一个扩展,我把它放在私有库中。希望这段代码有帮助

+0

感谢您的代码@Dinesh Kumar。 – user5598997

0

我想你不应该有一个startTimer所的模板。你应该在OnAppearing方法中有一个StartTimer(例如)。

当StartTimer事件上升时,您应该更改模型中的“Time”属性(将“Time”属性更改为ObservableCollection中的所有项目......您不应该使用“List”)。将此“时间”属性绑定到您的“timeL”字段。现在,如果您实施INotifyPropertyChanged,您的timeL字段应该会自动更新。

+0

感谢您的帮助@Alessandro。我已经投了票,但没有拿,因为我的名声较差。 – user5598997

相关问题