Получить проверенные элементы из списка - PullRequest
0 голосов
/ 08 января 2019

Я просто привыкаю к ​​MVVM и хочу обойтись без кода и определить все в моделях представления. комбинированный список представляет несколько вариантов выбора (работ). Я хотел бы запросить элементы, которые были проверены. К сожалению, я не могу получить к ним доступ. В текстовом поле все выбранные элементы должны отображаться в виде объединенной строки.

View-модель

class MainViewModel : BaseViewModel
    {
        #region Fields

        private ObservableCollection<EssayTypeViewModel> _essayTypes;
        private EssayTypeViewModel _selectedEssayTypes;

        #endregion


        public ObservableCollection<EssayTypeViewModel> EssayTypes
        {
            get => _essayTypes;
            set
            {
                if (_essayTypes == value) return;
                _essayTypes = value; OnPropertyChanged("EssayTypes");
            }
        }


        public EssayTypeViewModel SelectedEssayTypes
        {
            get => _selectedEssayTypes;
            set { _selectedEssayTypes = value; OnPropertyChanged("SelectedEssayTypes"); }
        }


        public MainViewModel()
        {

            // Load Essay Types
            EssayTypeRepository essayTypeRepository = new EssayTypeRepository();
            var essayTypes = essayTypeRepository.GetEssayTypes();
            var essayTypeViewModels = essayTypes.Select(m => new EssayTypeViewModel()
            {
                Text = m.Text
            });

            EssayTypes = new ObservableCollection<EssayTypeViewModel>(essayTypeViewModels);

        }
    }

1008 * XAML *

<ListBox x:Name="Listitems" SelectionMode="Multiple" Height="75" Width="200" ItemsSource="{Binding EssayTypes}" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding Text}" IsChecked="{Binding Checked}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <TextBox Text="{Binding Path=SelectedEssayTypes}" Grid.Column="0" Width="160" Height="25" Margin="0,140,0,0"/>

Ответы [ 3 ]

0 голосов
/ 08 января 2019

Вы можете подключить обработчик событий к событию PropertyChanged всех EssayTypeViewModel объектов в коллекции EssayTypes и вызвать событие PropertyChanged для свойства только для чтения MainViewModel, которое возвращает все выбранные элементы в виде объединенной строки:

public MainViewModel()
{
    // Load Essay Types
    EssayTypeRepository essayTypeRepository = new EssayTypeRepository();
    var essayTypes = essayTypeRepository.GetEssayTypes();
    var essayTypeViewModels = essayTypes.Select(m =>
    {
        var vm = EssayTypeViewModel()
        {
            Text = m.Text
        };
        vm.PropertyChanged += OnPropertyChanged;
        return vm;
    });

    EssayTypes = new ObservableCollection<EssayTypeViewModel>(essayTypeViewModels);
}

private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Checked")
        OnPropertyChanged("SelectedItems");
}

public string SelectedItems => string.Join(",", EssayTypes.Where(x => x.Checked).ToArray());

Для этого требуется класс EssayTypeViewModel для реализации интерфейса INotifyPropertyChanged (например, производный от вашего BaseViewModel класса).

0 голосов
/ 11 января 2019

мм8 ответ работает. Тем временем я придумал другой подход. Не на 100% совместим с MVVM, но работает и довольно прост.

XAML

<ListBox x:Name="ListItems" SelectionMode="Multiple" Height="75" Width="200" ItemsSource="{Binding CollectionOfItems}" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <CheckBox Content="{Binding Name}" IsChecked="{Binding Checked, Mode=TwoWay}" Unchecked="GetCheckedElements" Checked="GetCheckedElements" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <TextBox Text="{Binding SelectedItemsString, UpdateSourceTrigger=PropertyChanged}" Grid.Column="0" Width="160" Height="25" Margin="0,140,0,0"/>

Код позади

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();
        }


        private void GetCheckedElements(object sender, RoutedEventArgs e)
        {
            (DataContext as MainViewModel)?.FindCheckedItems();
            (DataContext as MainViewModel)?.ConcatSelectedElements();
        }

    }

Модель

public class Items
    {
        public bool Checked { get; set; }
        public string Name { get; set; }

    }

ItemsViewModel (BaseViewModel реализует только INotifyPropertyChanged)

class ItemsViewModel : BaseViewModel
    {
        private bool _checked;
        private string _name;

        public bool Checked
        {
            get => _checked;
            set
            {
                if (value == _checked) return;

                _checked = value;
                OnPropertyChanged("Checked");
            }
        }

        public string Name
        {
            get => _name;
            set
            {
                if (value == _name) return;

                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }

MainViewModel

public class MainViewModel : BaseViewModel
    {
        private string _selectedItemsString;
        private ObservableCollection<Items> _selectedItems;



        public ObservableCollection<Items> CollectionOfItems { get; set; }

        public ObservableCollection<Items> SelectedItems
        {
            get => _selectedItems;
            set
            {
                _selectedItems = value;
                OnPropertyChanged("SelectedItems");
            } 
        }


        public string SelectedItemsString
        {
            get => _selectedItemsString;
            set
            {
                if (value == _selectedItemsString) return;

                _selectedItemsString = value;
                OnPropertyChanged("SelectedItemsString");
            }
        }

        public MainViewModel()
        {
            CollectionOfItems = new ObservableCollection<Items>();
            SelectedItems = new ObservableCollection<Items>();




            CollectionOfItems.Add(new Items { Checked = false, Name = "Item 1" });
            CollectionOfItems.Add(new Items { Checked = false, Name = "Item 2" });
            CollectionOfItems.Add(new Items { Checked = false, Name = "Item 3" });

        }


        public void FindCheckedItems()
        {
            CollectionOfItems.Where(x => x.Checked).ToList().ForEach(y => SelectedItems.Add(y));
        }


        public void ConcatSelectedElements()
        {
            SelectedItemsString = string.Join(", ", CollectionOfItems.Where(x => x.Checked).ToList().Select(x => x.Name)).Trim();
        }
    }
0 голосов
/ 08 января 2019

Вы можете применить Mode = Two way к привязке флажка.

<CheckBox Content="{Binding Text}" IsChecked="{Binding Checked, Mode=TwoWay}"/>

затем вы можете перебрать коллекцию типов эссе, чтобы проверить, проверена ли запись элемента.

Например Пример кода может быть:

foreach (var essayTypeInstance in EssayTypes)
{
     if(essayTypeInstance.Checked)
     {
          // this value is selected
     }
}

Надеюсь, это поможет.

...