Пустое поле ListBox при привязке к заполненному ICollectionView - PullRequest
0 голосов
/ 07 августа 2020

Я пытаюсь реализовать фильтрацию на UserControl (который по сути является просто ListBox с шаблоном данных), используя ICollectionView.

Когда я привязываюсь к ICollectionView my LOAListBox пусто.

Мой xaml выглядит так:

<TextBox Text="{Binding SearchString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

<!-- LOA_List is a DependencyProperty which binds to ListBox.ItemsSource -->
<controls:LOAListBox LOA_List="{Binding FilteredView, Mode=OneWay}" />

И в моей модели представления я делаю это:

public class LOAViewModel : ViewModelBase
{
    public ICollectionView FilteredView { get; private set; }
    
    private string _searchString;
    public string SearchString
    {
        get => _searchString;
        set
        {
            _searchString = value;
            RaisePropertyChanged("SearchString");
            FilteredView.Refresh();
        }
    }

    private List<LOA> _available_LOAs;
    public List<LOA> Available_LOAs
    {
        get => _available_LOAs;
        set
        {
            _available_LOAs = value;
            RaisePropertyChanged("Available_LOAs");
        }
    }

    public LOAViewModel()
    {
        Available_LOAs = data.GetLOAData();
        FilteredView = CollectionViewSource.GetDefaultView(Available_LOAs);
        FilteredView.Filter = new Predicate<object>(o => Filter(o as LOA));
    }

    private bool Filter(LOA loa)
    {
        return SearchString == null || loa.Display_Name.Contains(SearchString);
    }
}

Во время отладки я вижу что Available_LOAs не пусто и после GetDefaultView FilteredView также имеет ту же коллекцию. Ошибок привязки нет. Я также сделал метод фильтра всегда возвращать true, чтобы исключить эту возможность.

Я чувствую, что должен пропустить какой-то шаг, но я проверил различные другие онлайн-примеры и ничего не могу найти ... подозрение в том, что это связано с тем, что я привязываюсь к ListBox, вложенному в UserControl, но я не понимаю, почему это имеет значение, когда он работает, если напрямую изменить привязку с FilteredView на Available_LOAs .

Обновить; это упрощенный код для LOAListBox:

XAML:

<UserControl>
    <ListBox ItemsSource="{Binding LOA_List, Mode=OneWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"/>
</UserControl>

Код программной части:

public partial class LOAListBox : UserControl
{

    public static readonly DependencyProperty DataSource = DependencyProperty.Register(nameof(LOA_List), typeof(List<LOA>), typeof(LOAListBox), new PropertyMetadata());
    public List<LOA> LOA_List
    {
        get => (List<LOA>)GetValue(DataSource);
        set => SetValue(DataSource, value);

    }

}

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Вы не можете привязать ICollectionView к свойству List<T>.

Измените тип вашего свойства зависимости на IEnumerable:

public static readonly DependencyProperty DataSource = DependencyProperty.Register(nameof(LOA_List), 
    typeof(IEnumerable), typeof(LOAListBox), new PropertyMetadata());
public IEnumerable LOA_List
{
    get => (IEnumerable)GetValue(DataSource);
    set => SetValue(DataSource, value);
}

В качестве примечания, вы также следует изменить имя свойства зависимости с «DataSource» на «LOA_ListProperty» (и удалить подчеркивание из обоих имен) в соответствии с соглашением об именах.

0 голосов
/ 10 августа 2020

После пошагового воспроизведения проблемы я в конце концов понял, что я не уведомляю об изменениях в FilteredView и, не помогая делу, я менял источник ICollectionView без переназначения ICollectionView ,

Итак, я сделал свое FilteredView стандартным свойством, которое вызывает RaisePropertyChanged():

private ICollectionView _filteredView;
public ICollectionView FilteredView
{
    get => _filteredView;
    set
    {
        _filteredView = value;
        RaisePropertyChanged("FilteredView");
    }
}

И когда я изменяю исходную переменную ICollectionView, я переназначаю на основе новой исходной коллекции :

FilteredView = CollectionViewSource.GetDefaultView(Available_Destination_LOAs);
FilteredView.Filter = new Predicate<object>(o => Filter(o as LOA));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...