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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ListView, доступ к Slider определённому в, GridView.CellTemplate 
:(
    Опции темы
CasperSC
Дата 6.8.2011, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 203
Регистрация: 27.11.2009

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



Всем привет. Ситуация такая: Есть UserControl в нём ListView. Я сделал DataTemplate для GridViewColumn.CellTemplate. В итоге получилось что-то вроде плейлиста, как вконтакте, то есть в каждой ListViewItem есть слайдер. Я хочу при воспроизведении трека, чтобы я мог управлять этим Slider'ом. Как к нему получить доступ? Например при событии SelectionChanged. Вообще что-то не въеду никак, как же сделать взаимодействие с Slider?
Код
        <ListView Margin="0" x:Name="lViewPlaylist" SelectionMode="Single" SelectionChanged="lViewPlaylist_SelectionChanged" 
                  Style="{DynamicResource ListViewStyle}" >
            <ListView.ItemContainerStyle>
            </ListView.ItemContainerStyle>
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Название" Width="400">
                     <GridViewColumn.CellTemplate>
                          <DataTemplate>
                             <StackPanel MinHeight="30" >
                                 <TextBlock Text="{Binding Title}"/>
                                    <Slider Name="slider" Margin="0,-3,0,-3" Width="277" Height="23" IsEnabled="False" 
HorizontalAlignment="Left" IsMoveToPointEnabled="True" Style="{DynamicResource SliderVolumeStyle}" 
ValueChanged="currentSlider_ValueChanged" Value="{Binding TrackPosition}" Maximum="{Binding TrackLength}"/>
                                </StackPanel>                 
                             </DataTemplate>        
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn DisplayMemberBinding="{Binding PlayTime}" Header="Продолжительность" Width="125" />
                </GridView>
            </ListView.View>
        </ListView>


На одном форуме посоветовали глядеть как сделано в примере и сделать у себя также:
Код
private void myList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (myList.SelectedItem != null)
    {
        object o = myList.SelectedItem;
        ListViewItem lvi = (ListViewItem)myList.ItemContainerGenerator.ContainerFromItem(o);
        TextBox tb = FindByName("myBox", lvi) as TextBox;
 
        if (tb != null)
                tb.Dispatcher.BeginInvoke(new Func<bool>(tb.Focus));
    }
}
 
private FrameworkElement FindByName(string name, FrameworkElement root)
{
    Stack<FrameworkElement> tree = new Stack<FrameworkElement>();
    tree.Push(root);
 
    while (tree.Count > 0)
    {
        FrameworkElement current = tree.Pop();
        if (current.Name == name)
                return current;
 
        int count = VisualTreeHelper.GetChildrenCount(current);
        for (int i = 0; i < count; ++i)
        {
                DependencyObject child = VisualTreeHelper.GetChild(current, i);
                if (child is FrameworkElement)
                        tree.Push((FrameworkElement)child);
        }
    }
 
    return null;
}


Но почему-то эта конструкция иногда возвращает null (комментарии в коде поясняют ситуацию, так что лучше их прочитать)?
Код
        public void SetSliderIsEnabledProperty(int sliderIndex, bool newValue)
        {
            ListViewItem lvi = null;
            if (lastIndex != sliderIndex)
            {
                //Вот эта беда иногда выдаёт null
                lvi = (ListViewItem)ListViewPlaylist.ItemContainerGenerator.ContainerFromItem(ListViewPlaylist.Items[sliderIndex]); 
                if (lvi == null)
                    Debug.WriteLine("-----------"); //Тут поставил точку останова, просто для отлова исключения, чтобы глянуть состояние объектов, замучался уже ловить этот баг
                
                lastIndex = sliderIndex;
                currentSlider = (Slider)FindByName("slider", lvi);
            }
            currentSlider.IsEnabled = newValue;
        }


Скриншот!
user posted image

Кстати о скриншоте. В момент срабатывания точки останова sliderIndex равен 0, а как видно на скриншоте под индексом 0 есть объект. То есть мы ищем ListViewItem как я понял через объект передаваемый в параметрах, но как опять же видно на скриншоте метод вернул null.

Это сообщение отредактировал(а) CasperSC - 6.8.2011, 14:25
PM MAIL   Вверх
Gvozdin
Дата 9.8.2011, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 9.8.2011
Где: Москва

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



Тут видимо играет роль виртуализация.

В случае с деревом с виртуализацией правильная последовательность поиска элемента описана в MSDN http://msdn.microsoft.com/en-us/library/ff407130.aspx#Y486
Можно по аналогии перенести к вам.

Не так просто в этом разобраться конечно, но уметь работать с виртаулизацией надо уметь smile

Алгоритм собственно сводится к запросу BringIntoView и ожидания пока ItemContainerGenerator сгенерирует элемент.

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

ContainerFromItem возвращает null в случае клика пользователем или вы тестируете?
--------------------
http://gvozdin.ru
PM MAIL WWW   Вверх
CasperSC
Дата 9.8.2011, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 203
Регистрация: 27.11.2009

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



Нет при программном выборе первого элемента например в большом списке, когда доиграл последний в списке трек, то надо переключиться на первый. Я просто отключил виртуализацию. Сейчас посмотрю ваш вариант и может применю его.
PM MAIL   Вверх
Gvozdin
Дата 9.8.2011, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 9.8.2011
Где: Москва

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



Сделали VirtualizingStackPanel.IsVirtualizing=False на ListBox?
Без виртуализации заработало?


Это сообщение отредактировал(а) Gvozdin - 9.8.2011, 20:13
--------------------
http://gvozdin.ru
PM MAIL WWW   Вверх
CasperSC
Дата 9.8.2011, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 203
Регистрация: 27.11.2009

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



Нет, немного по другому:
Код

        <ListView  ScrollViewer.CanContentScroll="False">

PM MAIL   Вверх
Gvozdin
Дата 9.8.2011, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 9.8.2011
Где: Москва

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



Тоже вариант %)
--------------------
http://gvozdin.ru
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




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


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

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