Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > WPF и Silverlight > MVVM и привязка к DataTemplate


Автор: Rohoss 5.5.2011, 14:57
Есть View - это окно, и соответственно ViewModel. Дальше у нас в окне расположен ListView, который биндится к данным ViewModel.
В ListView есть дататемплейт, который отрисовывает кнопку. К Кнопке привязана команда, которая находится в ViewModel. Примерно так:
Код

<ListView ItemsSource="{Binding viewModel}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Button">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="My Button" Command="{Binding MyCommand}" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>

Я хочу, чтобы при нажатии на кнопку сработала привязанная команда и произвела действие над объектом, который привязан к данному итему. То есть, у меня не получается передать сам объект, который привязан к данной кнопке в ViewModel, для того чтобы произвести над ним манипуляции.
Можно конечно привязывать SelectedItem и получать его при клике, но не факт что клик будет на кнопке выделенного элемента...

Автор: -Mikle- 6.5.2011, 06:24
Все очень просто:
Код

<Button Content="My Button" Command="{Binding MyCommand}" CommandParameter="{Binding}" />


Но тут есть еще один момент, ваша команда раположена в самом айтеме? Потому что вы биндитесь к текущему контексту данных, которым будет являться в этом случае сам айтем, а не модель представления. Для того чтобы забиндить в данном случае команду, надо явно прописать у биндинга Source на вашу модель.

Автор: Rohoss 6.5.2011, 10:46
-Mikle-, похоже вы меня не поняли... или я вас...

Цитата(-Mikle- @  6.5.2011,  06:24 Найти цитируемый пост)
Для того чтобы забиндить в данном случае команду, надо явно прописать у биндинга Source на вашу модель. 

Она там прописано, я просто код на примере упростил, вопрос в другом. Итем биндится к коллекции данных в ViewModel. И команда тоже находится в ViewModel, и она даже выполняется. Но выполняется она не так как мне бы хотелось, просто у меня SelectedItem с ListView тоже привязан к данным у ViewModel. И при нажатии на кнопку команда обрабатывается по отношению к выделенному итему, а я хочу чтобы она отрабатывалась не по отношению к выделенному, а по отношении к тому, на которому нажата кнопка. Он не обязательно является выделенным.

Добавлено через 1 минуту и 44 секунды
CommandParameter="{Binding}" - это интересно, но я опять же не представляю как всё это реализовать. Есди я передам в CommandParameter текущий итем, то как я в моделе узнаю где тот итем что мне надо. Получается что будет много итемов и много кнопок...

Автор: -Mikle- 6.5.2011, 12:48
Цитата(Rohoss @  6.5.2011,  13:46 Найти цитируемый пост)
CommandParameter="{Binding}" - это интересно, но я опять же не представляю как всё это реализовать. Есди я передам в CommandParameter текущий итем, то как я в моделе узнаю где тот итем что мне надо. Получается что будет много итемов и много кнопок...

Это то, что вам нужно. Задав параметр таким образом, вы будете передавать в команду датаконтекст кнопки, то бишь конкретного итема, а не SelectedItem. 
Код

private void ExecuteMyCommand(object parameter)
{
    // parameter тут, будет представлять итем в котором находится кнопка, а не SelectedItem.
}


Попробую еще объяснить по другому. У листвью DataContext задан как ваша модель, ок. Когда листвью генерит контейнеры (фактически ListViewItem) для итемов списка в вашей модели, он ложит созданному ListViewItem.DataContext = <итем из списка>. Далее, ваша кнопка полчается находится в контексте конкретного ListViewItem, а это значит в контексте конкретного айтема в списке, а не в контексте SelectedItem.

Автор: Rohoss 6.5.2011, 12:54
-Mikle-, спасибо  smile 

Всё дело в том, что я не знал как передаётся CommandParamete, я думал его тоже надо привязывать к ViewModel чтобы потом обрабатывать при вызове команды. А он оказывается передается параметром Execute. Тогда всё правильно и удобно получается. Спасибо.

Автор: -Mikle- 6.5.2011, 12:59
Не за что, всегда рад smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)