Xamarin Forms:如何处理从视图到视图模型的订阅事件(ListView - 搜索栏)

Xamarin Forms: How to handle a subcribe event from view to viewmodel (ListView - Search Bar)

全部,

我正在构建绑定 SearchText 的自定义 SearchableListView 属性。

public class SearchableListView : SfListView
   {
      #region Field

      /// <summary>
      /// Gets or sets the text value used to search.
      /// </summary>
      public static readonly BindableProperty SearchTextProperty =
          BindableProperty.Create(nameof(SearchText), typeof(string), typeof(SearchableListView), null, BindingMode.Default, null, OnSearchTextChanged);    
         
      /// <summary>
      /// Gets or sets the text value used to search.
      /// </summary>
      private string searchText;

      #endregion

      #region Property

      /// <summary>
      /// Gets or sets the text value used to search.
      /// </summary>
      public string SearchText
      {
         get 
         { 
            return (string)this.GetValue(SearchTextProperty); 
         }
         set 
         { 
            this.SetValue(SearchTextProperty, value); 
         }
      }

      #endregion

      #region Method

      /// <summary>
      /// Filtering the list view items based on the search text.
      /// </summary>
      /// <param name="obj">The list view item</param>
      /// <returns>Returns the filtered item</returns>
      public virtual bool FilterData(object obj)
      {
         if (this.SearchText == null)
         {
            return false;
         }

         return true;
      }

      /// <summary>
      /// Invoked when the search text is changed.
      /// </summary>
      /// <param name="bindable">The SfListView</param>
      /// <param name="oldValue">The old value</param>
      /// <param name="newValue">The new value</param>
      private static void OnSearchTextChanged(BindableObject bindable, object oldValue, object newValue)
      {
         var listView = bindable as SearchableListView;
         if (newValue != null && listView.DataSource != null)
         {
            listView.searchText = (string)newValue;
            listView.DataSource.Filter = listView.FilterData;
            listView.DataSource.RefreshFilter();
         }

         listView.RefreshView();
      }

      #endregion
   }

此视图绑定到通用列表项,因此 FilterData 上的对象可以是任何类型。 IDK 如何将事件订阅到 FilterData,它在视图模型上执行方法,我可以在其中将我的对象转换为我已知的类型。

这是我的 ViewModel。

public abstract class ListPageViewModel<T> : BaseViewModel where T : class, IEntity
{      
  private T _selectedItem;
  private string searchText;
  private ObservableCollection<T> _items;

  public ListPageViewModel()
  {
     this.NewCommand = new Command(NewItem);         
     this.ItemSelectedCommand = new Command(ItemSelected);         
  }     

  public ObservableCollection<T> Items
  {
     get => _items;
     set
     {
        this.SetProperty(ref this._items, value);
     }
  }

  public T SelectedItem
  {
     get => _selectedItem;
     set
     {
        this.SetProperty(ref this._selectedItem, value);
     }
  }

  public string SearchText
  {
     get => searchText;
     set
     {
        this.SetProperty(ref this.searchText, value);
     }
  }     

  public ICommand NewCommand { get; set; } 

  public ICommand ItemSelectedCommand { get; set; }       

  public async virtual void LoadItemsAsync()
  {
     Items = new ObservableCollection<T>(await localDataService.GetAllAsync<T>());
  }

  public async virtual void NewItem(object obj)
  {
     
  }

  public async virtual void ItemSelected(object obj)
  {
     var eventArgs = obj as Syncfusion.ListView.XForms.ItemTappedEventArgs;
     navigationService.NavigateTo(EditViewModel, "editEntity", eventArgs.ItemData, false);
     await MtTaskExtensions.CompletedTask;
  }
}

既然是虚方法,难道就不能像这样重写ViewModel中的方法吗?

public class MyListPageViewModel : ListPageViewModel<MyClass>
{

    public override bool FilterData(object obj)
    {
        if(obj is MyClass myObj)
        {
            // Do something
        }
        return base
            .FilterData(obj);
    }
}