【问题标题】:complexed Issue with hiding ListView Xamarin Forms隐藏 ListView Xamarin 表单的复杂问题
【发布时间】:2019-09-04 21:17:34
【问题描述】:

我有一个搜索栏,其中 Text 属性绑定到我的 ViewModel 中的字符串属性。

我在搜索栏中也有Behaviors,因此每次更改文本时,都会使用NewTextValue 作为查询字符串在对象列表中进行搜索。

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

当从现在可见的列表视图中选择一个项目时,我使用该项目填充我的SearchBarText 属性,之后我无法将它隐藏在代码中。所有尝试都失败了,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 继承自 BaseViewModel,后者继承 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); } }
}

【问题讨论】:

  • “之后我无法将其隐藏在代码中” - 您尝试执行此操作的代码在哪里?我没看到。
  • 嗨,用TextChanged的方法检查一下。也许当文本为空时,方法不显示空。您可以显示TextChanged的代码,我会检查它。
  • @Jason 我把代码剪短了,所以帖子不会很长,但是,在SearchText 属性设置使用SetProperty 之后,我所拥有的是FilteredOccupationsVisible = false。那没有用。
  • @JuniorJiang-MSFT 我正在使用 PrismEventToCommand,因此当文本更改时会调用 FilterOccupationsList()。对不起,我没有说清楚
  • @steve 也许你可以尝试在 Model 中使用 INotifyPropertyChanged ,也不确定 prism 是否可以使用它。看看这个关于INotifyPropertyChanged

标签: c# xaml listview xamarin.forms xamarin-forms-4


【解决方案1】:

如果没有在 SearchBar 中使用 Behaviors ,您可以尝试使用 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来做,则需要在MyViewModel中添加ICommand的实例来调用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);
                });    
    }
    ...
}

【讨论】:

  • 谢谢,我已经通过TrueFalse 玩了一会儿FilteredOccupationsVisible 解决了这个问题。 DeletegateCommand 是一个 PrismMvvm 框架类。再次感谢您的意见。
  • @steve 太好了,很高兴解决了它!有时间可以在回答中分享。然后其他人会看到解决方案。
猜你喜欢
  • 1970-01-01
  • 2020-02-07
  • 1970-01-01
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
相关资源
最近更新 更多