Cedric Marx
Cedric Marx

Reputation: 11

Databinding to command inside of listview not working in UWP/MVVM-Light

I want to have a Delete button for every element in my ListView, I searched stackoverflow but none answer my question.

I tried giving my ListView a x:Name="QuizListView" and using ElementName inside the ListView to bind the command to the button.

QuizOverview.xaml

<Page
    x:Name="QuizOverviewPage"
    x:Class="UwpApp.View.QuizOverview"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UwpApp.View"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    DataContext="{Binding QuizOverviewInstance, Source={StaticResource Locator}}">

    <StackPanel Margin="20">
        <TextBlock Text="Quizzen" FontSize="48"/>
        <ListView x:Name="QuizListView" ItemsSource="{Binding Quizzes}" Margin="0,20" SelectionMode="Single" SelectionChanged="QuizListView_SelectionChanged">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ListViewItem>
                        <StackPanel Orientation="Horizontal">
                            <Border CornerRadius="10" BorderBrush="Black" BorderThickness="2" Height="100" Width="400" VerticalAlignment="Center">
                                <TextBlock Text="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="36"></TextBlock>
                            </Border>
                            <Button VerticalAlignment="Center" Padding="20" Margin="20">Edit</Button>
                            <Button VerticalAlignment="Center" Padding="20" Margin="0" Command="{Binding Path=DataContext.DeleteQuizCommand, ElementName=QuizListView}" CommandParameter="{Binding}">Delete</Button>
                        </StackPanel>
                    </ListViewItem>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button Padding="20" Command="{Binding CreateQuizCommand}">Add New Quiz</Button>
    </StackPanel>
</Page>

QuizOverviewViewModel.cs

    public class QuizOverviewViewModel : ViewModelBase
    {
        public string Title { get; set; }
        public ObservableCollection<Quiz> Quizzes { get; set; }

        public RelayCommand<Quiz> DeleteQuizCommand { get; set; }

        public RelayCommand CreateQuizCommand { get; set; } 

        public QuizOverviewViewModel()
        {
            Title = "Quizzen";
            Quizzes = new ObservableCollection<Quiz> { new Quiz(1, "Test Quiz 1"), new Quiz(2, "Test Quiz 2"), new Quiz(3, "Test Quiz 3") };

            DeleteQuizCommand = new RelayCommand<Quiz>(DeleteQuiz);
            CreateQuizCommand = new RelayCommand(CreateQuizTest);
        }   

        public void DeleteQuiz(Quiz quiz)
        {
            Quizzes.Remove(Quizzes.Single(i => i.Id == quiz.Id));
        }

        public void CreateQuizTest()
        {
            Quizzes.Add(new Quiz(4, "Test Quiz Creation!"));
        }
    }

Quiz.cs

namespace UwpApp.Model
{
    public class Quiz
    {
        public long Id { get; set; }
        public string Name { get; set; }

        public Quiz(long id, string name)
        {
            Id = id;
            Name = name;
        }
    }
}

The Button does nothing with my current code, while the command does work outside of the ListView.

Upvotes: 1

Views: 619

Answers (1)

Nico Zhu
Nico Zhu

Reputation: 32775

Databinding to command inside of listview not working in UWP/MVVM-Light

The problem is that you insert ListViewItem in to DataTemplate. It will cause that ListViewItem contains sub-ListViewItem in the Visual Tree and you could not access correct DataContext with element name in your button. Please remove ListViewItem from your code.

<DataTemplate>
    <StackPanel Orientation="Horizontal">
        <Border CornerRadius="10" BorderBrush="Black" BorderThickness="2" Height="100" Width="400" VerticalAlignment="Center">
            <TextBlock Text="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="36"></TextBlock>
        </Border>
        <Button VerticalAlignment="Center" Padding="20" Margin="20">Edit</Button>
        <Button VerticalAlignment="Center" Padding="20" Margin="0" Command="{Binding Path=DataContext.DeleteQuizCommand, ElementName=QuizListView}" CommandParameter="{Binding}">Delete</Button>
    </StackPanel>
</DataTemplate>

Upvotes: 2

Related Questions