2017-05-06 18 views
1

私はxamarinフォームIOSを使用してバインドにいくつかの問題があります。 私はバインディングを持っています。最初のページが表示されたら、画面の中央に読み込みラベルが表示されます。XamarinフォームIOSでのバインディングの問題とOnAppearing問題

後リストビューでデータがロードされます。読み込みラベルはバインドによって非表示になり、リストビューが表示されます。

私はこのレポを持っているAndroidのプロジェクトで

Xamarin forms IOS Android Test

それは正常に動作します。 reproプロジェクトのiosでは、アプリケーションが最初に読み込まれると読み込みラベルが非表示になり、画面をタップすると表示されます。 続けると読み込みラベルが消えて空白の画面が表示されますが、画面を再度タップするとリストデータビューが表示されます。

私はこれがxamarinのバグだと思っていますが、バインディングが間違っていると思っています。私はこの問題に感謝したいと思います。 私は2つの他の問題もあります。リストビュー項目をクリックしてナビゲートすると、オンアピアリングがトリガーされないため、データがリフレッシュされません。

アンドロイドでは問題なく起動されます。上記の手順のように画面をタップした後に、時にはオンザアが発生することがあります。 最後の問題は、タブIOSの切り替えが表示されても起動しないことです。アンドロイドでそれがします。 この問題に関するお手伝いをさせていただきます。私はこれらの問題の解決策を広範に調査しており、まだ見つけてお答えしていません。 ありがとう!

以下は、役立つコードスニペットです。このコードは、テストしたい場合はGitHubリポジトリにもあります。私はプロパティを通知し使用していますXAML

<Label x:Name="xEmptyListView" 
     FontSize="16" 
     HorizontalOptions="CenterAndExpand" 
     HorizontalTextAlignment="Center" 
     VerticalOptions="CenterAndExpand"    
     Text="{Binding ListViewVisibleText, Mode=TwoWay}" 
     IsVisible="{Binding IsListViewLabelEmptyVisible, Mode=TwoWay }"/> 

    <ListView x:Name="ItemsListView" 
      ItemsSource="{Binding Items}" 
      VerticalOptions="FillAndExpand" 
      HasUnevenRows="true" 
      RefreshCommand="{Binding LoadItemsCommand}" 
      IsPullToRefreshEnabled="true" 
      IsRefreshing="{Binding IsBusy, Mode=OneWay}" 
      CachingStrategy="RecycleElement" 
      ItemSelected="OnItemSelected" 
      IsVisible="{Binding IsListViewVisible, Mode=TwoWay}" 
      IsEnabled="{Binding IsActivityRunning, Mode=TwoWay, Converter={StaticResource InverseBooleanConverter}}"> 

のViewModelに

private bool activityRunning { get; set; } 

    public bool IsActivityRunning 
    { 
     get { return activityRunning; } 
     set 
     { 
      if (activityRunning == value) 
       return; 

      activityRunning = value; 
      OnPropertyChanged("IsActivityRunning"); 
     } 
    } 

    private string listViewVisibleText { get; set; } 
    public string ListViewVisibleText 
    { 
     get { return listViewVisibleText; } 
     set 
     { 
      if (listViewVisibleText == value) 
       return; 

      listViewVisibleText = value; 
      OnPropertyChanged("ListViewVisibleText"); 
     } 
    } 



    private bool listViewLabelEmptyVisible { get; set; } 

    public bool IsListViewLabelEmptyVisible 
    { 
     get 
     { 
      if (Items == null || Items.Count == 0) 
      { 
       if (IsBusy) 
       { 
        ListViewVisibleText = "Loading..."; 
       } 
       else 
       { 

        ListViewVisibleText = "No Items found"; 


       } 
       listViewLabelEmptyVisible = true; 
      } 
      else 
      { 
       ListViewVisibleText = string.Empty; 
       listViewLabelEmptyVisible = false; 
      } 

      OnPropertyChanged("IsListViewLabelEmptyVisible"); 
      return listViewLabelEmptyVisible; 
     } 
    } 

    private bool listViewVisible { get; set; } 

    public bool IsListViewVisible 
    { 
     get 
     { 
      if (Items == null || Items.Count == 0) 
      { 
       listViewVisible = false; 
      } 
      else 
      { 
       listViewVisible = true; 
      } 

      OnPropertyChanged("IsListViewVisible"); 
      return listViewVisible; 
     } 
    } 

XAML.cs

protected override void OnAppearing() 
     { 
      base.OnAppearing(); 


       viewModel.LoadItemsCommand.Execute(null); 
     } 

が変更されました。これは、これは私のビューモデルがnotifypropertyが変更のために継承するものである標準コード

であるあなたは、これはあるプロジェクトxamarinテストを作成すると、観察対象

public class BaseViewModel : ObservableObject 

から継承ベースのviewmodel

public class ItemsViewModel : BaseViewModel 

それは見た目です。

public class ObservableObject : INotifyPropertyChanged 
    { 
     /// <summary> 
     /// Sets the property. 
     /// </summary> 
     /// <returns><c>true</c>, if property was set, <c>false</c> otherwise.</returns> 
     /// <param name="backingStore">Backing store.</param> 
     /// <param name="value">Value.</param> 
     /// <param name="propertyName">Property name.</param> 
     /// <param name="onChanged">On changed.</param> 
     /// <typeparam name="T">The 1st type parameter.</typeparam> 
     protected bool SetProperty<T>(
      ref T backingStore, T value, 
      [CallerMemberName]string propertyName = "", 
      Action onChanged = null) 
     { 
      if (EqualityComparer<T>.Default.Equals(backingStore, value)) 
       return false; 

      backingStore = value; 
      onChanged?.Invoke(); 
      OnPropertyChanged(propertyName); 
      return true; 
     } 

     /// <summary> 
     /// Occurs when property changed. 
     /// </summary> 
     public event PropertyChangedEventHandler PropertyChanged; 

     /// <summary> 
     /// Raises the property changed event. 
     /// </summary> 
     /// <param name="propertyName">Property name.</param> 
     protected void OnPropertyChanged([CallerMemberName]string propertyName = "") 
     { 
      var changed = PropertyChanged; 
      if (changed == null) 
       return; 

      changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

アイテムがロードされたときに活動走行が設定されますなど このアンドロイド上のすべての作品。 IOSはそうではありません。

+0

いくつかのサンプルコードを追加できますか? – Mike

答えて

0

私はこれを考え出しました。私がラベルを表示してリストビューを隠したり、その逆をしたりしてバインディングを処理していたのは、IOSが要求を処理する方法を妨害していました。私はバインディングを削除し、リストビューでプロパティ変更ハンドラを使用してコントロールを直接設定しました。タブ、戻るボタンなどの問題を修正しました。

関連する問題