Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WPF, Silverlight Новый топик    Ответить
 ListView с checkbox и событие  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 263
Есть у меня такой класс:
public class MyInfo
{
  public int ID { get; set; }
  public string Remark { get; set; }
  public IsChecked { get; set; }
}

Потом я создаю ObservableCollection<MyInfo> Data { get; set; } и делаю биндинг к ListView (у которого есть колонка с чекбоксами). Как теперь для кнопки менять IsEnabled в зависимости от того, есть галка в колонке с чекбоксами или нет. В рамках MVVM.
20 июн 16, 15:59    [19315031]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21989
Кнопка-то где? В темплейте строки или вообще вне ListView?
20 июн 16, 16:43    [19315267]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 263
Да, кнопка вне ListView...
20 июн 16, 16:48    [19315290]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21989
Ну можно привязать её IsEnabled к Linq-выражению с Any, а при изменении чекбокса генерировать событие PropertyChanged для этого свойства.

События CheckedEvent и UnheckedEvent - всплывающие - можно ловить их централизованно на уровне листбокса.
20 июн 16, 17:04    [19315363]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 263
Тогда такой вопрос, немного отвлеченный от темы: как для всей коллекции (списка) элементов подписаться на изменения свойства? Пусть одного IsChecked в данном случае. То что, класс MyInfo будет реализовывать интерфейс INotifyPropertyChanged это понятно...
20 июн 16, 17:13    [19315389]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21989
Если хочется подписываться на события самой модели - кто мешает? Можно через CollectionChanged (и смотреть добавленные элементы), либо просто сделать собственное централизованное добавление в коллекцию.
20 июн 16, 17:38    [19315543]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 263
Я имею ввиду изменение значения одного из свойств коллекции/списка...
20 июн 16, 17:49    [19315593]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21989
И я вроде о том же. В чем конкретно вопрос?
20 июн 16, 17:50    [19315600]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4038
зачем тут ListView? когда достаточно ItemsControl?
Еще я для себя сделал UniversalBox, где в качестве контейнера может выступать любой из существующих ContentControl'ов, что довольно удобно.
20 июн 16, 18:33    [19315767]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21989
Roman Mejtes
зачем тут ListView? когда достаточно ItemsControl?
почему ты так думаешь? Может ему нужно ширину столбцов менять или, скажем, прямоугольное выделение делать.... В контексте вопроса, в общем-то, без разницы
Roman Mejtes
UniversalBox, где в качестве контейнера может выступать любой из существующих ContentControl'ов
А в чем удобство большее, чем шаблон Item-а?
20 июн 16, 19:00    [19315858]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4038
Shocker.Pro
Roman Mejtes
UniversalBox, где в качестве контейнера может выступать любой из существующих ContentControl'ов
А в чем удобство большее, чем шаблон Item-а?

Визуальное дерево получается короче
20 июн 16, 21:35    [19316360]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 263
ListView здесь нужен в явном виде не нужен, но для привычного внешнего вида оставлен. А по теме, сделал так: во ViewModel'е в конструкторе я в цикле foreach подписываюсь на событие изменения свойства объекта, в обработчике меняю свойство ViewModel'и IsCheckedLV, которое управляет поведением кнопки. Так же я во ViewModel'и же обрабатываю событие CollectionChanged, в обработчике которого вызываю все тот же метод, определяющий количество чекнутых галок и меняющий свойство IsCheckedLV. Работает. Хотел для идеальности передавать в метод новые элементы, чтобы только для них подписываться на изменения
(ObservableCollection<MyInfo>)e.NewItems

но тут возникла ошибка приведения типов...
21 июн 16, 13:44    [19318710]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21989
неудивительно, оно ведь не является тем, к чему вы хотите привести.

а зачем вам приведение к какому-то типу, если NewItems реализует IEnumerable?
21 июн 16, 13:56    [19318766]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 263
Например, чтобы передать эти элементы в метод, который будет
Data.ForEach(x => x.ProperyChanged += MyPropertyChanged)

То есть - в начале метод бы принимал всю коллекцию, а потом - только добавленные элементы. Ну так планировалось)
21 июн 16, 14:14    [19318870]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21989
Qwe.Qwe1
метод, который будет Data.ForEach
так чем не устраивает обычный foreach?
21 июн 16, 14:41    [19319025]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 263
private void SetHandler(ObservableCollection<MyInfo> data)
{
  data.ForEach(x => x.ProperyChanged += MyPropertyChanged);
}

SetHandler((ObservableCollection<MyInfo>)e.NewItems); // error
21 июн 16, 14:48    [19319062]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21989
Всё грустно....

private void SetHandler(IEnumerable<MyInfo> data)
{
  foreach (var item in data)
  {
    data.ProperyChanged += MyPropertyChanged
  }
}

SetHandler(e.NewItems.Cast<MyInfo>())
21 июн 16, 14:56    [19319110]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 263
Итого:
private bool _isCheckedLV;
public bool IsCheckedLV
{
  get { return _isCheckedLV; }
  set { _isCheckedLV= value; OnPropertyChanged(); }
}

public MyViewModel()
{
  <...>
  SetHandlerToEventIsCheckedChanged(Data);
  Data.CollectionChanged += Data_CollectionChanged;
}

private void SetHandlerToEventIsCheckedChanged(IEnumerable<MyInfo> data)
{
  data.ForEach(x => x.PropertyChanged += InfoPropertyChanged);
}

private void Data_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
  SetHandlerToEventIsCheckedChanged(e.NewItems.Cast<MyInfo>());
  SetChecked();
}

private void InfoPropertyChanged(object sender, PropertyChangedEventArgs e)
{
  if (e.PropertyName == "IsChecked")
  {
    SetChecked(); 
  } 
}

private void SetChecked()
{
  IsCheckedLV = Data.Any(x => x.IsChecked);
}
21 июн 16, 15:18    [19319202]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4038
вообще использовать foreach для e.NewItems у ObsevableCollection бессмысленно, по причине того, что в ней вообще нет методов "групповой" вставки и удаления. А классы унаследованные от ICollectionView, который оборачивают коллекцию при любом связывании с UI строго проверяют эти значения на то, чтоб они не были больше или равны 1ницы (0 или 1).

Я был сам этому удивлён, когда исследовал работу CollectionView'ров с целью запилить свои с блекджеком и всем остальным.

Короче говоря, в e.NewItems технически не может быть больше 1 элемента, а если они там окажутся, то мы получим исключение
System.NotSupportedException' Additional information: Range actions are not supported.
(при условии, что данная ObservableCollection<T> связана с ItemsControl'ом)

По этому, вся эта возня во круг foreach пустая трата времени, вы ожидаете увидеть там несколько элементов, но их всегда будет меньше 2
21 июн 16, 19:03    [19320170]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 21989
Да, это, конечно, недостаток ObservableCollection.

Тем не менее, ты работаешь с интерфейсом IEnumerable, а не с ObservableCollection, поэтому стоит все-таки сделать цикл, чтобы избежать плохообнаруживаемых проблем с потенциальным рефакторингом.

Кстати, я делал обертку над ObservableCollection, которая имеет AddRange и выдает единственный PropertyChanged.
21 июн 16, 19:30    [19320264]     Ответить | Цитировать Сообщить модератору
 Re: ListView с checkbox и событие  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4038
Shocker.Pro
Да, это, конечно, недостаток ObservableCollection.

Тем не менее, ты работаешь с интерфейсом IEnumerable, а не с ObservableCollection, поэтому стоит все-таки сделать цикл, чтобы избежать плохообнаруживаемых проблем с потенциальным рефакторингом.

Кстати, я делал обертку над ObservableCollection, которая имеет AddRange и выдает единственный PropertyChanged.

проблема не в ObservableCollection, а в ItemContainerGenerator'е, создать свою коллекцию имплантирующую INotifyCollectionChanged нет ни каких проблем, но при использовании такой коллекции в качество источника для UI будет ошибка, при вставке более 1 элемента. Так как, когда мы связываем нашу коллекцию со свойством ItemsSource, ItemsControl создает View'у для этой коллекции и задает её в качестве Items, к котором потом подписывается генератор контейнеров. И всё это добро умеет работать только по элементно.

а само событие CollectionChanged поддерживает множественные изменения, для этого там даже конструктор соответствующий есть и в чистом коде, без UI всё должно работать как обычно.
21 июн 16, 21:01    [19320578]     Ответить | Цитировать Сообщить модератору
Все форумы / WPF, Silverlight Ответить