Нужен простой пример каскадных комбо-боксов с использованием MVVM - PullRequest
0 голосов
/ 09 сентября 2010

Нужен простой пример каскадных комбинированных блоков с использованием MVVM

Wpf / Silverlight

1 Ответ

8 голосов
/ 10 сентября 2010

Если я понимаю ваш вопрос, вы хотите, чтобы следующий комбинированный список заполнялся данными, основанными на предыдущем значении.

У меня есть общая ViewModel, которую вы можете захватить список элементов и выбранного элемента

class ItemListViewModel<T> : INotifyPropertyChanged where T : class
{
    private T _item;
    private ObservableCollection<T> _items;

    public ItemListViewModel()
    {
        _items = new ObservableCollection<T>();
        _item = null;
    }

    public void SetItems(IEnumerable<T> items)
    {
        Items = new ObservableCollection<T>(items);
        SelectedItem = null; 
    }

    public ObservableCollection<T> Items
    {
        get { return _items; }
        private set
        {
            _items = value;
            RaisePropertyChanged("Items");
        }
    }

    public T SelectedItem
    {
        get { return _item; }
        set
        {
            _item = value;
            RaisePropertyChanged("SelectedItem");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Затем создайте основную модель представления, которая будет связана с DataContext представления. Пусть методы Load делают то, что вы хотите

class MyViewModel : INotifyPropertyChanged
{
    public MyViewModel()
    {
        First = new ItemListViewModel<string>();
        Second = new ItemListViewModel<string>();
        Third = new ItemListViewModel<string>();

        First.PropertyChanged += (s, e) => Update(e.PropertyName, First, Second, LoadSecond);
        Second.PropertyChanged += (s, e) => Update(e.PropertyName, Second, Third, LoadThird);

        LoadFirst();
    }

    public ItemListViewModel<string> First { get; set; }
    public ItemListViewModel<string> Second { get; set; }
    public ItemListViewModel<string> Third { get; set; }

    private void LoadFirst()
    {
        First.SetItems(new List<string> { "One", "Two", "Three" });
    }
    private void LoadSecond()
    {
        Second.SetItems(new List<string> { "First", "Second", "Third" });
    }
    private void LoadThird()
    {
         Third.SetItems(new List<string> { "Firsty", "Secondly", "Thirdly" });
    }

    private void Update<T0, T1>(string propertyName, ItemListViewModel<T0> parent, ItemListViewModel<T1> child, Action loadAction)
        where T0 : class
        where T1 : class
    {
        if (propertyName == "SelectedItem")
        {
            if (parent.SelectedItem == null)
            {
                child.SetItems(Enumerable.Empty<T1>());
            }
            else
            {
                loadAction();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

И, на ваш взгляд, где-то есть этот код.

    <ComboBox ItemsSource="{Binding First.Items}" SelectedItem="{Binding First.SelectedItem}" />
    <ComboBox ItemsSource="{Binding Second.Items}" SelectedItem="{Binding Second.SelectedItem}" />
    <ComboBox ItemsSource="{Binding Third.Items}" SelectedItem="{Binding Third.SelectedItem}" />

Вы можете сделать рефакторинг, чтобы сделать его лучше, использовать MVVM-фреймворки или получить ItemListViewModel специально для списка элементов и загрузить его для лучшей инкапсуляции. Это до вас.

Если какое-либо родительское значение поля со списком будет изменено, тогда все дочерние списки будут очищены.

НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...