0

У меня есть 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>

    &lt;TextBox Text=&quot;{Binding QuizModel.Name}&quot; Grid.Column=&quot;0&quot; Grid.Row=&quot;0&quot;/&gt;
    &lt;TextBox Text=&quot;{Binding Quest}&quot; Grid.Column=&quot;1&quot; Grid.Row=&quot;0&quot;/&gt;
    &lt;StackPanel  Grid.Column=&quot;2&quot; Grid.Row=&quot;0&quot;&gt;
        &lt;Button Content=&quot;Add&quot; Command=&quot;{Binding AddQuizNodeCommand}&quot;/&gt;
        &lt;Button Content=&quot;Save&quot; Command=&quot;{Binding SaveQuizCommand}&quot;/&gt;
    &lt;/StackPanel&gt;
    &lt;ListBox ItemsSource=&quot;{Binding QuizModel.QuizNodes}&quot; Grid.ColumnSpan=&quot;3&quot; Grid.Row=&quot;1&quot;&gt;
        &lt;ListBox.ItemTemplate&gt;
            &lt;DataTemplate&gt;
                &lt;Grid&gt;
                    &lt;Grid.RowDefinitions&gt;
                        &lt;RowDefinition/&gt;
                        &lt;RowDefinition/&gt;
                    &lt;/Grid.RowDefinitions&gt;
                    &lt;WrapPanel Grid.Row=&quot;0&quot;&gt;
                        &lt;TextBlock Text=&quot;{Binding Question}&quot;/&gt;
                        &lt;TextBox Text=&quot;&quot;/&gt;
                        &lt;Button Content=&quot;Add answer&quot; Command=&quot;&quot;/&gt;
                    &lt;/WrapPanel&gt;
                    &lt;Expander Header=&quot;Ответы&quot; Grid.Row=&quot;1&quot;&gt;
                        &lt;ListBox ItemsSource=&quot;{Binding Answers}&quot;&gt;
                            &lt;ListBox.ItemTemplate&gt;
                                &lt;DataTemplate&gt;
                                    &lt;WrapPanel&gt;
                                        &lt;TextBlock Text=&quot;{Binding Str}&quot;/&gt;
                                        &lt;CheckBox IsChecked=&quot;{Binding IsCorrect}&quot;/&gt;
                                    &lt;/WrapPanel&gt;
                                &lt;/DataTemplate&gt;
                            &lt;/ListBox.ItemTemplate&gt;
                        &lt;/ListBox&gt;
                    &lt;/Expander&gt;
                &lt;/Grid&gt;
            &lt;/DataTemplate&gt;
        &lt;/ListBox.ItemTemplate&gt;
    &lt;/ListBox&gt;
&lt;/Grid&gt;

</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

  • https://ru.stackoverflow.com/a/724594/220553 – EvgeniyZ Nov 06 '23 at 10:04
  • Спасибо за ответ. Теперь команду видно в разметке, но ее вызов не происходит. – AlexandrAsh Nov 07 '23 at 19:17
  • А при чем тут vm? Не придумывайте своего, внимательно посмотрите на ответ. Вот откройте XAML и посмотрите, как там располагаются элементы, поймете, что они располагаются в неком древовидном порядке, где некоторые находятся друг в друге, а некоторые содержат своих потомков. Вот у вас все, что внутри ItemTemplate - это потомки, которые имеют свои данные, вам нужны данные родителя, а значит и найти надо родителя. То есть, у вас должно быть Binding DataContext.AddAnswerCommand (ибо у родителя наша VM это DataContext), AncestorType=ListBox (ибо он родитель всех внутренних объектов). – EvgeniyZ Nov 07 '23 at 19:39
  • Спасибо за исправление. – AlexandrAsh Nov 08 '23 at 06:40

0 Answers0