Привязать ListBox к другому ListBox - PullRequest
2 голосов
/ 09 декабря 2011

У меня есть 2 списка, если вы щелкнете по элементу в верхнем, то нижний фильтрует несколько результатов. Я пытаюсь изучить WPF и MVVM, и мне интересно, если это правильный способ сделать это. Это лучший способ?

Вот что я сделал:

class VisitInfoViewModel : ViewModelBase
{
    List<ServiceType> serviceTypes;
    List<ServiceType> allServiceTypes;
    public VisitInfoViewModel()
    {
        ServiceCategories = ServiceCategory.Categories;
        allServiceTypes = ServiceType.ServiceTypes;
    }

    public List<ServiceCategory> ServiceCategories { get; set; }
    public List<ServiceType> ServiceTypes 
    {
        get
        {
            return serviceTypes;
        }
    }

    public ServiceCategory SelectedServiceCategory
    {
        get { return null; }
        set
        {
            serviceTypes = allServiceTypes.FindAll(st => st.ServiceCategoryGuid.Equals(value.Guid));
            OnPropertyChanged("ServiceTypes");
        }
    }
}

и фрагмент MainWindow.xaml

<ListBox ItemsSource="{Binding Path=VisitInfo.ServiceCategories}" 
         SelectedItem="{Binding Path=VisitInfo.SelectedServiceCategory}" 
         ItemTemplate="{StaticResource listBoxTemplate}"  
         Height="112" 
         HorizontalAlignment="Left" 
         Margin="6,30,0,0" 
         Name="lbxServiceCategory" 
         VerticalAlignment="Top" 
         Width="366" />

<ListBox ItemsSource="{Binding Path=VisitInfo.ServiceTypes}" 
         ItemTemplate="{StaticResource listBoxTemplate}" 
         HorizontalAlignment="Left" 
         Margin="6,0,0,19" 
         Name="lbxServiceType" 
         Width="366" 
         Height="121"
         VerticalAlignment="Bottom" />

также, почему я не должен просто добавить EventHandler для selectedItemChanged в свой список? Кажется, намного проще и понятнее использовать обработчик событий. Я думаю, что это потому, что если бы я сделал это, то больше не было бы MVVM ... это правильно? Что бы вы сделали и каковы лучшие практики?

1 Ответ

0 голосов
/ 09 декабря 2011

То, что вы делаете, в основном хорошо - хотя я бы лично сделал SelectedServiceCategory «реальным» свойством (с сохраненным значением).

Разница с MVVM и выполнением этого кода заключается в том, что вы работаете с данными. Если вы сделаете так, чтобы «Текущая категория» изменила типы, то вы будете работать исключительно с данными и вообще не беспокоиться об интерфейсе пользователя. Вы можете изменить категорию с помощью любого механизма, и пользовательский интерфейс всегда будет оставаться актуальным.

Лично я бы предложил написать это примерно так:

class VisitInfoViewModel : ViewModelBase
{
    List<ServiceType> allServiceTypes;
    public VisitInfoViewModel()
    {
        ServiceCategories = ServiceCategory.Categories;
        allServiceTypes = ServiceType.ServiceTypes;
    }

    // This can use a private setter...
    public IEnumerable<ServiceCategory> ServiceCategories { get; private set; }

    private ServiceCategory currentCategory;
    public ServiceCategory CurrentServiceCategory
    {
        get { return this.currentCategory; }
        set
        {
            if (this.currentCategory != value)
            {
                this.currentCategory = value;
                ServiceTypesInCurrentCategory = allServiceTypes.Where(st => st.ServiceCategoryGuid.Equals(this.currentCategory.Guid));
                OnPropertyChagned("CurrentServiceCategory");
                OnPropertyChanged("ServiceTypes");
            }
        }
    }

    public IEnumerable<ServiceType> ServiceTypesInCurrentCategory { get; private set; }
}

Это дает полную свободу изменять CurrentServiceCategory в коде или через Xaml без каких-либо обработчиков событий. Это также делает вашу ViewModel полностью связанной с данными - вы не знаете или не заботитесь о том, что используется для отображения этого - если у вас есть что-то в вашем представлении, которое устанавливает CurrentServiceCategory, все остается синхронизированным правильно .

также, почему я не должен просто добавить EventHandler для selectedItemChanged в свой список? Кажется, намного проще и понятнее использовать обработчик событий. Я думаю, что это потому, что если бы я сделал это, то больше не было бы MVVM ... это правильно?

Вы можете сделать это, но на данном этапе это, как правило, нарушение MVVM. Основная проблема заключается в том, что вы будете связывать реализацию с этим обработчиком событий - делая это, вы в основном «блокируете» поведение, основанное на вашем коде в вашем View, для этой конкретной реализации View. Сохраняя его "чистым" с точки зрения MVVM, вы можете свободно изменять View (то есть: может быть, когда-нибудь захотите переключиться на комбинированный список для ServiceCategories), не касаясь кода ViewModel вообще ...

...