3
votes

I have more of a question than problem. I have my listView in XAML:

<ListView Margin="25,10,25,10" Name="BookListView" ItemsSource="{Binding Books}" DockPanel.Dock="Top">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock Text="{Binding Name}"/>
                <StackPanel>
                    <TextBlock Text="Number: " />
                    <TextBlock Text="{Binding Number}" />
                </StackPanel>

                <Button Content="Read" Visibility="Hidden" Name="ReadButton" Command="{Binding ReadCommand}"/>
            </Grid>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="True">
                    <Setter TargetName="ReadButton" Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

And for formality my DataContext:

public MainWindow()
{
    InitializeComponent();
    DataContext = new BookListViewModel();
}

My listView itemsSource is binded to observableCollection of elements of my class called "Book" in my viewModel and everything works great (in this code snippet I deleted all code which specify looks of this window).
My problem is that each element in my list contains a button which shows up, when element is clicked. If I bind my command as I did in this code, application will expect my ReadCommand to be in Book class code, which as I always thought violate the MVVM Pattern. So my question is - is this solution acceptable in MVVM pattern? If no, then how can I go back from binding to observableList in listView to binding the viewModel in my button?

1

1 Answers

3
votes

Having a ReadCommand property in the Book class does not violate MVVM in any way. However, it might be more reasonable and convenient to have the ReadCommand in your view model. In that case, you can use RelativeSource to get to the ListView's DataContext, which is in fact the view model:

<Button Content="Read" Visibility="Hidden" Name="ReadButton"
        Command="{Binding Path=DataContext.ReadCommand, RelativeSource={RelativeSource AncestorType=ListView}}"/>