0

我有一个搜索栏,其属性Text绑定到我的ViewModel.

Behaviors在搜索栏中也有,因此每次更改文本时,都会在使用NewTextValue传递给作为查询字符串的对象列表中完成搜索。

我遇到的问题是,在ListView将非空字符串传递给我的搜索/过滤命令之前,我将其设为不可见(显然.. :))。我试图强制隐藏ListView几个场景,例如,如果所有文本都从搜索栏中删除。

当从现在可见的列表视图中选择一个项目时,我使用该项目来填充Textmy 的属性SearchBar,之后我无法将其隐藏在代码中。所有尝试都失败了,ListView仍然可见。注意:我明确地单独创建了一个隐藏按钮并看到它有效,所以我想知道我是否不能将隐藏视图与设置搜索栏Text属性联系起来。

看法

<SearchBar Text="{Binding SearchText}">
                    <SearchBar.Behaviors>
                        <prismBehaviors:EventToCommandBehavior EventName="TextChanged"
                                                               Command="{Binding FilterOccupationsListCommand}"
                                                               EventArgsParameterPath="NewTextValue"/>
                    </SearchBar.Behaviors>
                </SearchBar>
                <ListView ItemsSource="{Binding FilteredOccupations}" IsVisible="{Binding FilteredOccupationsVisible}"  SelectedItem="{Binding Occupation, Mode=TwoWay}">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <TextCell Text="{Binding Name}"/>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

请注意:我的 ViewModel 继承自BaseViewModelwhich 继承INotifyPropertyChangedSetProperty()是通知属性的内容。这在 MvvmCross、Prism 等中很常见。

视图模型

public class MyViewModel : BaseViewModel
{
    public DelegateCommand<string> FilterOccupationsListCommand { get; }
    public MyViewModel()
    {
        FilterOccupationsListCommand = new DelegateCommand<string>(FilterOccupationsList);
    }
    private void FilterOccupationsList(string query)
    {
        if (!string.IsNullOrWhiteSpace(query))
        {
            FilteredOccupationsVisible = true;
            var searchResult = Occupations.Where(x => x.Name.ToLower().Contains(query));
            FilteredOccupations = new ObservableCollection<Occupation>(searchResult);
        }
        else
            FilteredOccupationsVisible = false;
    }

    private Occupation _occupation;
    public Occupation Occupation
    {
        get => _occupation;
        set
        {
            SetProperty(ref _occupation, value);
            SearchText = value.Name;
        }
    }

    private string _name;
    public string Name { get => _name; set => SetProperty(ref _name, value); }
    private string _searchText;
    public string SearchText 
    { 
        get => _searchText; 
        set { 
              SetProperty(ref _searchText, value); 
              FilteredOccupationsVisible = false;
            } 
    }

    private bool _filteredOccupationsVisible;
    public bool FilteredOccupationsVisible { get => _filteredOccupationsVisible; set => SetProperty(ref _filteredOccupationsVisible, value); }

    public ObservableCollection<Occupation> _filteredOccupations = new ObservableCollection<Occupation>();
    public ObservableCollection<Occupation> FilteredOccupations { get => _filteredOccupations; set { SetProperty(ref _filteredOccupations, value); } }
}
4

1 回答 1

1

如果不使用Behaviorsin SearchBar,您可以尝试使用TextChanged自己的方法。

<SearchBar x:Name="MySearchBar" Text="SearchText" TextChanged="SearchBar_TextChanged" />

在 ContentPage 中,当文本在这里发生变化时:

MyViewModel myViewModel = new MyViewModel();    

private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
{
    Console.WriteLine("new -- " + e.NewTextValue + "-- old -- " + e.OldTextValue);
    Console.WriteLine("MyEntry --" + MySearchBar.Text);
    //Here can invoke FilterOccupationsList of MyViewModel 
    myViewModel.FilterOccupationsList(MySearchBar.Text);
}

否则,如果使用 Command 来做,则需要添加 instance of ICommandinMyViewModel来调用FilterOccupationsList

public class MyViewModel : BaseViewModel
{
    public ICommand FilterOccupationsListCommand { private set; get; }
    ...

    public MyViewModel()
    {
       FilterOccupationsListCommand = new Command<string>((NewTextValue) =>
                {
                    // Pass value to FilterOccupationsList.
                    Console.WriteLine("SearchBar new text --" + NewTextValue);
                    FilterOccupationsList(NewTextValue);
                });    
    }
    ...
}
于 2019-09-06T01:53:52.820 回答