2017-04-11 16 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

相關問題