Я пытаюсь создать базовый пользовательский интерфейс и привязку в UWP, чтобы обернуть голову вокруг него, но у меня возникают проблемы с доступом к кнопке в элементе списка.
У меня есть кнопка, при нажатии на которую создается новый объект, который добавляется в мою коллекцию ObservableCollection, которая затем добавляет новый элемент в мой ListView
XMAL
<ListView Grid.Row = "1" ItemsSource = "{x:Bind counts}" x:Name = "buttonsView" Margin = "5,0" Background = "White" Foreground = "#FF5059AB">
<ListView.ItemTemplate>
<DataTemplate x:DataType = "local:Counter">
<StackPanel Orientation = "Vertical">
<TextBlock Text = "{x:Bind CountValue, Mode=TwoWay}" FontWeight = "Black"/>
<Button Click = "Increment_Click" Content = "Increment"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
C#
public class Counter
{
private int count;
public Counter()
{
count = 0;
}
public int CountValue
{
get
{
return count;
}
set
{
count = value;
}
}
}
public sealed partial class MainPage : Page
{
ObservableCollection<Counter> counts = new ObservableCollection<Counter>();
public MainPage()
{
this.InitializeComponent();
}
private void Increment_Click(object sender, RoutedEventArgs e)
{
// ?
}
private void AddCounter_Click(object sender, RoutedEventArgs e)
{
counts.Add(new Counter());
}
}
Это работает.
Но когда я нажимаю кнопку в StackPanel, вызывается метод Increment_Click, но я не уверен, что делать в этот момент. Я хотел бы получить доступ к объекту Counter, получив индекс элемента ListView и используя его для индексации в ObservableCollection.
Как мне выяснить, какой индекс добавленного элемента ListView?





Вместо события следует использовать Command и CommandParameter. Затем вы должны привязать Command к команде, реализованной в Counter, и CommandParameter к элементу (например, {Binding}).
Однако вы можете достичь своей цели с помощью события Click, а также с помощью DataContext:
private void Increment_Click(object sender, RoutedEventArgs e)
{
var button = (Button)sender;
var counter = (Counter)button.DataContext;
//...
}
Обычно DataContext по умолчанию наследуется от родителя, если вы не укажете иное, поэтому в этом случае DataContext является текущим элементом списка.
Это предпочтительнее, потому что шаблон MVVM защищает отдельную бизнес-логику от представления. В идеале это означает, что код программной части представления должен быть пустым (за исключением конструктора страницы). Конечно, это невозможно в 100% случаев, но если у вас есть возможность иметь команду над самими элементами, это лучше. Еще одно преимущество состоит в том, что вы можете в любой момент изменить экземпляр команды и выполнить другое действие (например, на основе текущего состояния элемента), и все это будет прозрачным для представления.
Спасибо, что сработало. Я также реализовал привязку команды и получил ее. Почему предпочтительнее этот метод?