1

Использую в WPF ListView. Что бы при каждом добавлении нового элемента в ListView, в одну из его колонок добавлялась кнопка, я написал следующий код (в коде оставил только одну колонку с кнопкой чтобы не засорять код).

<ListView Name="ListViewDictionary" Margin="10,39,92,10">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Озвучить">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Button Tag ="{Binding vocalizeButton}" Width="20" Height="20" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

Кнопки успешно создаются. Но как получить ссылку на них в C# коде или вообще как-то с ними взаимодействовать?

UPD: Просто уточню что меня интересует обработка нажатий этих кнопок.

Rivand
  • 2,084
  • У вас не должно быть ссылок на них в коде. У вас должна быть коллекция классов, внутри класса должны быть все эти свойства (vocalizeButton например) и уже эта коллекция привязывается к ListView. Посмотрите как в WPF работаю привязки. – EvgeniyZ Oct 09 '19 at 18:27
  • @EvgeniyZ ну вот vocalizeButton тут как раз свойство типа Button. Как мне привязать создающийся тут Button к vocalizeButton? – Rivand Oct 09 '19 at 19:07
  • 1
    Button - это контрол, его место только в XAML, не более.В классе у вас должны быть обычные типы (int/string и др.). Что касается привязок - посмотрите например этот ответ, либо куча других примеров, где работают с привязками. – EvgeniyZ Oct 09 '19 at 19:16
  • 1
    @mrFieldy вам как и многим другим кто перешел на WPF придется отучиться от нахождения объектов в XAML. тут философия совсем другая. все делается через привязки, шаблоны и т.д. почитайте на www.professorweb.ru – axmed2004 Oct 09 '19 at 19:18
  • @EvgeniyZ да это я понимаю. Я к тому, что если мне нужно обработать события нажатия созданной в xaml кнопке, то механизм привязки тут бесполезен. С привязками я примерно знаком. – Rivand Oct 09 '19 at 19:22
  • @axmed2004 а как мне по другому добавить кнопку или другой контрол в ListView? (Большое спасибо за ссылку) – Rivand Oct 09 '19 at 19:23
  • механизм привязки тут бесполезен - это почему же? Я вам дал ссылку на ответ, где название, клик и позиция в Grid у кнопки привязаны к классу, к простому классу. Так почему же бесполезны? В WPF не используются обычные события Click, да, можно, но это костыли, правильным подходом будет использование привязки к команде (ICommand/RelayCommand и др.). – EvgeniyZ Oct 09 '19 at 19:27
  • @EvgeniyZ ок, сейчас перечитаю, спасибо большое. – Rivand Oct 09 '19 at 19:28
  • 1
    @axmed2004 Это миф, не нужно никуда переучиваться. Использование шаблонов и привязок никак не исключает программное взаимодействие с элементами управления. – MSDN.WhiteKnight Oct 10 '19 at 05:14

1 Answers1

1

Я не вижу, как для обработки нажатий кнопок нужно получать к ним доступ из кода. Механизм шаблонов точно так же умеет устанавливать и обработчики событий для того, что он генерирует:

<DataTemplate>
     <Button Width="20" Height="20" Click="Button_Click" />
</DataTemplate>

Но, если нужно получить доступ в коде к элементу, сгенерированному шаблоном, конечно, это можно сделать. Проще всего проходить по визуальному дереву; правда следует делать это аккуратно и не завязывать код на определенную его структуру, которая может зависеть от темы оформления. Например, вот так можно найти Button с определенным значением свойства Tag в визуальном дереве:

public static Button FindButton(Visual vis, string tag)
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(vis); i++)
    {                
        Visual child = (Visual)VisualTreeHelper.GetChild(vis, i);

        Button button = child as Button;
        if (button != null)
        {
            if (tag == (string)button.Tag) return button; 
        }

        Button res = FindButton(child,tag);
        if (res != null) return res;
    }
    return null;
}

Button button = FindButton(ListViewDictionary, "...");