2017-04-18 3 views
1

質問を適切に書式設定してもわからない場合は、教えてください。しかし、私は単にビューセル内の値に背景色をバインドしようとしています。私は実際にこれが働いています。問題は、私が値を更新するとき、私は背景色の変化を見ることはありません。実装は少し複雑ですが、ここに私のコードです。OnBindingContextChangedを使用してListView(リサイクルキャッシュ戦略)でバリューコンバータを使用しようとしています

だから、基本的に私はちょうど私のレイアウトを構築ViewCell(OnBindingContextChanged)

... 
ShowReadOverlay.SetBinding(Xamarin.Forms.VisualElement.BackgroundColorProperty, new Xamarin.Forms.Binding(".", Xamarin.Forms.BindingMode.TwoWay, new XamarinMobile.Converters.GridCellBackgroundColorConverter(), null, null, null)); 
... 

。私はOnBindingContextChangedメソッドでバインディングを設定する関連するコードを投稿することにしました。誰かが他のコードを必要としている場合、私はそれを追加してうれしいです、ちょうどそれが適切かどうかわからない。私のViewCellクラスは、ちょうどViewCellを継承する単純なクラスです。

public class GridCellBackgroundColorConverter : Xamarin.Forms.IValueConverter 
{ 
    #region IValueConverter Members 

    public object Convert(object value, Type targetType, object parameter, 
     System.Globalization.CultureInfo culture) 
    { 
     try 
     { 

      var cell = (XamarinMobile.ViewModels.GridCellViewModel)value; 

      if(cell.HasRead) 
      { 
       //return with shadow 
       return Xamarin.Forms.Color.FromRgba(0,0,0,0.6); 
      } else 
      { 
       //return no shadow 
       return Xamarin.Forms.Color.FromRgba(0, 0, 0, 0.0); 
      } 

     } catch(System.Exception ex) 
     { 
      return null; 
     } 

    } 

    public object ConvertBack(object value, Type targetType, object parameter, 
     System.Globalization.CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 

    #endregion 
} 

シンプル:

は、ここに私のコンバータです。できます。今ここには難しい部分があります。だから私が描いているグリッドは、ストーリーのセルを含むリストビューです。ユーザーは画像をクリックしてストーリーページに移動します。ユーザーがストーリーページにいるときは、グリッドに戻って別のストーリーに移動するか、左右にスワイプして別のストーリーに移動できます。ユーザーがグリッドからストーリーページに移動すると、セルは更新された状態になります。しかし、ユーザーがグリッドからではなく別のストーリーにスワイプすると、それが私の問題です。私のストーリーのページでは、グリッドセルを繰り返し処理するロジックがあり、現在開いているストーリー(スワイプしたストーリー)を見つけ、グリッド内にあるかどうかを確認し、グリッド内にある場合はセルのHasReadプロパティを更新します。このように:

  //find the cell in the grid (if exists) 
      ViewModels.GridCellViewModel cell = App.GridCells.Where(x => x.StoryId == App.Story.StoryId).FirstOrDefault(); 
      if (cell != null) 
      { 
       cell.HasRead = true; 
      } 

これは機能しますが、値変換器がプロパティを変更するようには誘発しません。私は間違って何をしていますか?プロパティを更新してバリュー・コンバータを起動させるにはどうしたらいいですか?

+0

何?くそー..onbindingcontextの変更を介してビューセルをバインドする方法についての少しの洞察もありませんか? – jdmdevdotnet

答えて

0

私は、あなたが技術的にViewRead自体ではなく、HasReadプロパティにバインドされているので、コンバータが起動していないと思います。 HasReadを設定すると、INotifyPropertyChangedを実装していると仮定して、バインディングをトリガして値コンバータを呼び出すPropertyChangedEventを発生させます。ただし、バインディングはビューセル自体を指しているため、その変更が発生したときにトリガされ、そのオブジェクトの他の場所でプロパティの変更が無視されます。

考えられる解決方法は、HasRead( '。'の代わりに)を指すようにバインディングを変更し、ビューセルを取り込むのではなくブール値を直接期待するようにコンバータを更新することです。これは、コンバータに関係なく、より良い方法です。

これは、xamarinフォームアプリケーションで一般的に推奨されているmvvmパターンに実際に従っているわけではありません。私の提案は、あなたのストーリーモデル(ロジックが必要な場合は独自のStoryViewModelsにラップされています)を保持するプロパティを持つビューモデルを持ち、VMおよびModelクラスがINotifyPropertyChangedを実装していることを確認することです。 VMをページのデータコンテキストにし、リストをあなたのリストビューソースにバインドすると、リストビューのitemtemplateの内容はそれぞれのストーリーにバインドされます。各ストーリーは、更新されたコンバータを介して背景色にバインドするHasReadプロパティを持つことができます。このよう

<ContentPage 
x:Class="Stack_Stories.MainPage" 
xmlns="http://xamarin.com/schemas/2014/forms" 
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
xmlns:local="clr-namespace:Stack_Stories"> 
<ContentPage.BindingContext> 
    <local:StoriesViewModel x:Name="VM" /> 
</ContentPage.BindingContext> 
<ContentPage.Resources> 
    <ResourceDictionary> 
     <local:StoryReadBackgroundColorConverter x:Key="HasReadColor" /> 
    </ResourceDictionary> 
</ContentPage.Resources> 

<ListView ItemsSource="{Binding Stories}"> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
      <ViewCell> 
       <Grid x:Name="StoryGrid" BackgroundColor="{Binding HasRead, Converter={StaticResource HasReadColor}}"> 
        <Button Command="{Binding ToggleReadCommand}" Text="{Binding Name}" /> 
       </Grid> 
      </ViewCell> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

public class StoryViewModel : INotifyPropertyChanged 
{ 
    private string _name = ""; 
    public string Name 
    { 
     get { return _name; } 
     set { _name = value; OnPropertyChanged(); } 
    } 

    private bool _hasRead = false; 
    public bool HasRead 
    { 
     get { return _hasRead; } 
     set { _hasRead = value; OnPropertyChanged(); } 
    } 

    private Command _toggleRead; 
    public Command ToggleReadCommand  
    { 
     get 
     { 
      return _toggleRead 
       ?? (_toggleRead = new Command(() => HasRead = !HasRead)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
public class StoriesViewModel : INotifyPropertyChanged 
{ 
    public StoriesViewModel() 
    { 
     // add sample stories 
     Stories.Add(new StoryViewModel { Name = "First Story" }); 
     Stories.Add(new StoryViewModel { Name = "Second Story", HasRead=true }); 
    } 

    private ObservableCollection<StoryViewModel> _stories = new ObservableCollection<StoryViewModel>(); 
    public ObservableCollection<StoryViewModel> Stories 
    { 
     get { return _stories; } 
     set { _stories = value; OnPropertyChanged(); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

public class StoryReadBackgroundColorConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (!(value is bool)) return null; 

     return (bool)value ? Color.FromRgba(0, 0, 0, 0.6) : Color.FromRgba(0, 0, 0, 0.0); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

はい私はそれを私のビューモデルに縛り付けました。魅力のように働いた。 ViewCellではレイアウトが設定されていますが、ビューモデルを更新すると変更されるので、混乱します。それにもかかわらず、私はあなたの答えをマークしたので、同様のアプローチを取った:) – jdmdevdotnet

関連する問題