У меня есть ListBox и в каждом элементе кнопка. Как я могу привязать команду к этой кнопке и узнать в каком элементе была нажата кнопка. Использую MVVM.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d"
xmlns:vm="clr-namespace:AAAcasino.ViewModels.ClientViewModels.AdminViewModels">
<DataTemplate DataType="{x:Type vm:CreationQuizViewModel}">
<Grid d:DataContext="{d:DesignInstance vm:CreationQuizViewModel}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Text="{Binding QuizModel.Name}" Grid.Column="0" Grid.Row="0"/>
<TextBox Text="{Binding Quest}" Grid.Column="1" Grid.Row="0"/>
<StackPanel Grid.Column="2" Grid.Row="0">
<Button Content="Add" Command="{Binding AddQuizNodeCommand}"/>
<Button Content="Save" Command="{Binding SaveQuizCommand}"/>
</StackPanel>
<ListBox ItemsSource="{Binding QuizModel.QuizNodes}" Grid.ColumnSpan="3" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0">
<TextBlock Text="{Binding Question}"/>
<TextBox Text=""/>
<Button Content="Add answer" Command=""/>
</WrapPanel>
<Expander Header="Ответы" Grid.Row="1">
<ListBox ItemsSource="{Binding Answers}">
<ListBox.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Str}"/>
<CheckBox IsChecked="{Binding IsCorrect}"/>
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Expander>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</DataTemplate>
internal class CreationQuizViewModel : ViewModel, IPageViewModel
{
#region IPage
public string Title => "Создание викторины";
public MainWindowViewModel MainViewModel { get; set; }
public void SetAnyModel(object? model)
{
QuizModel = (QuizModel)model;
}
#endregion
private QuizModel? _quizModel = new QuizModel();
public QuizModel? QuizModel
{
get => _quizModel;
set => Set(ref _quizModel, value);
}
private string? _quest;
public string Quest
{
get => _quest;
set => Set(ref _quest, value);
}
#region command
public ICommand AddQuizNodeCommand { get; set; }
private void OnAddQuizNodeCommand(object param)
{
QuizNode node = new QuizNode();
node.Question = Quest;
QuizModel.AddQuizNode(node);
}
private bool CanAddQuizNodeCommand(object param) => true;
public ICommand SaveQuizCommand { get; set; }
private void OnSaveQuizCommand(object param)
{
Task.Run(() =>
{
int existance = (from q in MainWindowViewModel.applicationContext.quizModels.ToList()
where q == QuizModel
select q).Count();
if (existance > 0)
MainWindowViewModel.applicationContext.Update(QuizModel);
else
MainWindowViewModel.applicationContext.Add(QuizModel);
MainWindowViewModel.applicationContext.SaveChanges();
});
MainViewModel.SelectedPageViewModel = MainViewModel.ClientPageViewModels[(int)NumberClientPage.ADMIN_PAGE];
}
private bool CanSaveQuizCommand(object parameter) => (QuizModel.Name != "" && QuizModel.Name != null);
#endregion
public CreationQuizViewModel()
{
AddQuizNodeCommand = new LamdaCommand(OnAddQuizNodeCommand, CanAddQuizNodeCommand);
SaveQuizCommand = new LamdaCommand(OnSaveQuizCommand, CanSaveQuizCommand);
}
}
internal class QuizModel :ViewModel
{
private int _id;
public int ID
{
get => _id;
set => _id = value;
}
private string? _name = null;
public string? Name
{
get => _name;
set => Set(ref _name, value);
}
private ObservableCollection<QuizNode> _quizNodes = new ObservableCollection<QuizNode>();
public ObservableCollection<QuizNode> QuizNodes { get => _quizNodes; }
public void AddQuizNode(QuizNode node) { _quizNodes.Add(node); }
public void RemoveQuizNode(QuizNode node) { _quizNodes.Remove(node); }
}
internal class Answer : ViewModel
{
private int _id;
public int ID
{
get => _id;
set => _id = value;
}
private string _str;
public string Str
{
get => _str;
set => Set(ref _str, value);
}
private bool _correctness = false;
public bool IsCorrect
{
get => _correctness;
set => Set(ref _correctness, value);
}
}
В QuizNode коллекция Answer и string Question
ItemTemplate- это потомки, которые имеют свои данные, вам нужны данные родителя, а значит и найти надо родителя. То есть, у вас должно бытьBinding DataContext.AddAnswerCommand(ибо у родителя наша VM этоDataContext),AncestorType=ListBox(ибо он родитель всех внутренних объектов). – EvgeniyZ Nov 07 '23 at 19:39