Модераторы: gambit, Kefir, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как подписаться на события в случае привязки? ListView 
V
    Опции темы
Rohoss
Дата 8.1.2011, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Есть два ListView
Код

    <Grid>
        <ListView Name="lv1" Margin="25,0,272,0"></ListView>
        <ListView Name="lv2" Margin="245,0,52,0"></ListView>
    </Grid>


в первый добавляем элементы
Код

            ListViewItem lvi1 = new ListViewItem();
            lvi1.Content = "c1";
            ListViewItem lvi2 = new ListViewItem();
            lvi2.Content = "c2";
            lv1.Items.Add(lvi1);
            lv1.Items.Add(lvi2);

а второй привязываем
Код

            List<string> list = new List<string>();
            list.Add("s1");
            list.Add("s2");
            lv2.ItemsSource = list;

В первом случае подписаться на событие очень легко
Код

        lvi1.MouseDoubleClick += new MouseButtonEventHandler(lvi_MouseDoubleClick);

        private void lvi_MouseDoubleClick(Object sender, MouseButtonEventArgs e)
        {
            MessageBox.Show(sender.ToString());
        }


А как подписаться во втором случае?


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Kefir
Дата 9.1.2011, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 22
Всего: 87



Расскажу вкратце:
Во втором случае контейнеры для даты будут сгенерированы автоматически самим ListView. На момент когда ты привязываешь ItemsSource контейнеров ещё нет, поэтому привязаться сложно. В ситуации когда контейнеры уже созданы для получения контейнеров можно использовать
Код

lv2.ItemContainerGenerator.ContainerFromItem(someDataItem);
// или
lv2.ItemContainerGenerator.ContainerFromIndex(someIndex);


Теперь насчёт генерации самих контейнеров. ItemContainerGenerator как раз за это отвечает. Если я не ошибаюсь, то lv2.UpdateLayout() заставит его сгенерировать нужные контейнеры прямо на месте и, если повезёт, то ты сможешь получить готовый контейнер. Однако это не очень хорошо - лучше привязываться к событию ItemContainerGenerator.StatusChanged и там уже колдовать.

Последнее - почему может "не повезти". Если у тебя хост-панель внутри ListView виртуальная (по крайней мере у ListBox она такая), то значит, что контейнер будет создан только в ситуации, если его надо показать пользователю. То есть всё что за пределами видимости сгенерировано не будет и ты так и получишь null.

На первый взгляд оно может выглядеть слишком пакостно, но в этом всём есть логика. smile Удачи!
PM MAIL WWW Skype   Вверх
Rohoss
Дата 9.1.2011, 00:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Kefir, спасибо, как раз то что нужно  smile 

Цитата(Kefir @  9.1.2011,  00:07 Найти цитируемый пост)
На первый взгляд оно может выглядеть слишком пакостно,

Дак, так и кажется  smile . Но я так понимаю всегда лучше привязываться нежели создавать ListViewItem


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Kefir
Дата 9.1.2011, 00:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 22
Всего: 87



Цитата(Rohoss @  9.1.2011,  00:17 Найти цитируемый пост)
Но я так понимаю всегда лучше привязываться нежели создавать ListViewItem

Я, честно говоря, вообще уже не помню когда в последний раз создавал контейнеры вручную. Всё на привязке данных завязано - шаблоны, дататриггеры и подобное. А на события у контейнеров приходилось подписываться только по праздникам. Ну и виртуализация, как ни крути.

Цитата(Rohoss @  9.1.2011,  00:17 Найти цитируемый пост)
Дак, так и кажется

Ощущение пакости проходит если попытаться написать такую схему с автогенерацией самому - приходит понимание зачем всё это надо и почему так работает smile

Рад был помочь.
PM MAIL WWW Skype   Вверх
Rohoss
Дата 9.1.2011, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Цитата(Kefir @  9.1.2011,  00:07 Найти цитируемый пост)
Однако это не очень хорошо - лучше привязываться к событию ItemContainerGenerator.StatusChanged и там уже колдовать.

Это событие происходит множество раз, и даже тогда, когда ListViewItem'ы ещё не созданы. Но это не проблема, можно проверить их существования. Ну дело вот в чём, в событии ItemContainerGenerator.StatusChanged мы ведь подписываем необходимое нам события для ListViewItem, например lvi1.MouseDoubleClick +=. Однако, так как событие ItemContainerGenerator.StatusChange довольно часто происходит, мы получаем кучу подписок на lvi1.MouseDoubleClick. Эту проблему конечно можно решить например с помощью System.Reflection, или можно что-то писать в тегах ListViewItem... Но может быть в WPF предусмотрено для этого решение?


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Kefir
Дата 9.1.2011, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 22
Всего: 87



Ах да, забыл одну возможность - в стиле у контейнеров можно просто добавить <EventSetter>. Тогда можешь привязать эвент там и не мучаться с генератором.
PM MAIL WWW Skype   Вверх
Rohoss
Дата 9.1.2011, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Цитата(Kefir @  9.1.2011,  12:18 Найти цитируемый пост)
Ах да, забыл одну возможность - в стиле у контейнеров можно просто добавить <EventSetter>. Тогда можешь привязать эвент там и не мучаться с генератором. 

Не совсем понял... Под контейнером вы подразумеваете ListView? Если так, то я не знаю как добавить стиль для ListViewItem, они ведь привязуются... Если вы под контейнером понимаете ListViewItem, то его ведь всё равно нужно получить с помощью ItemContainerGenerator... Если можно приведите маленький пример  smile 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Kefir
Дата 9.1.2011, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 22
Всего: 87



Нет, я имею в виду стиль сгенерированных контейнеров для дата-итемов.

Подредактируйте так:
Код

<ListView>
  <ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
      <EventSetter Event="MouseDoubleClick" Handler="ListViewItem_MouseDoubleClick"/>
    </Style>
  </ListView.ItemContainerStyle>
</ListView>

И вуаля - каждый контейнер будет автоматом привязан к обработчику ListViewItem_MouseDoubleClick ;)
PM MAIL WWW Skype   Вверх
Rohoss
Дата 9.1.2011, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Kefir, это отличное решение  smile   через пару дней ещё один плюс поставлю

и что ещё в этой решении мне нравится, в параметр sender обработчика ListViewItem_MouseDoubleClick передаётся не текущий ListViewItem, а непосредственно привязанный элемент коллекции, что очень таки в духе виртуализации  smile 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Rohoss
Дата 9.1.2011, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Хотя с другой стороны, этот вариант не даст возможности получить доступа к данному ListViewItem в обработчике события...


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Kefir
Дата 9.1.2011, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 22
Всего: 87



Rohoss, я не помню чего там в сендере (я предполагал, что туда будет передан сам ListViewItem. Но если там действительно передаётся сам дата итем, то контейнер можно спокойно получать через ItemContainerGenerator smile Раз пришло событие дабл-клик, значит, что пользователь видит этот самый итем на экране и генератор тебе отдаст правильный ListViewItem. 

И на всякий случай замечу, что у ItemContainerGenerator есть ещё метод ItemFromContainer, который является методом ContainerFromItem только наоборот ;) Так что внутри обработчика ты можешь спокойно получать хоть сам дата итем, хоть его сгенерированный ListViewItem.
PM MAIL WWW Skype   Вверх
Rohoss
Дата 10.1.2011, 00:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Всё же ListViewItem передаётся в sender"е, это я не туда посмотрел  smile 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




[ Время генерации скрипта: 0.0813 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.