Кнопка WPF в ListView не может видеть команду в ViewModel

<StackPanel>
        <!--<Button Command="{Binding GetOddsCommand}" CommandParameter="{Binding}" />-->

    <ListView 
        ItemsSource="{Binding Links}"
        >
        <ListView.ItemTemplate>
            <DataTemplate>
                <Border>
                    <Button Command="{Binding GetOddsCommand}" CommandParameter="{Binding}">
                        <TextBlock >
                        <Hyperlink NavigateUri="http://www.onet.pl" >
                            <TextBlock Text="{Binding}" />
                        </Hyperlink>
                    </TextBlock>
                    </Button>
                </Border>
            </DataTemplate>
        </ListView.ItemTemplate>

у меня есть приложение MVVM. В viewmodel у меня есть GetOddsCommand:

public ICommand GetOddsCommand
{
    get
    {
        if (_getOddsCommand == null)
            _getOddsCommand = new RelayCommand(param => GetOdds());
        return _getOddsCommand;
    }
}

private void GetOdds()
{

}

когда я раскомментирую первую кнопку, помещенную в команду StackPanel, работает хорошо. Отладчик шаг в get, а затем, когда я нажимаю команду отладчик шаг в метод GetOdds. Но он не работает во второй кнопке, которая находится в ListView. Похоже, вторая кнопка не может видеть GetOddsCommand, но я не понимаю, почему

спасибо

2 ответов


положить кнопку и внутри нее гиперссылку не имеет большого смысла... Что вы ожидаете, когда вы нажмете на гиперссылку?
В любом случае, следующий код вызовет вашу команду:

<ListView ItemsSource="{Binding Links}" x:Name="ListView1">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Border>
                    <Button Command="{Binding ElementName=ListView1, Path=DataContext.GetOddsCommand}" CommandParameter="{Binding}">
                         <TextBlock Text="{Binding}" />
                    </Button>
                </Border>
            </DataTemplate>
        </ListView.ItemTemplate>
</ListView>

обратите внимание, что используемый DataContext - это ListView не из ListViewItem...
Возможно, вы захотите сделать такую же привязку для CommandParameter - зависит от того, что вы действительно хотите.

Теперь, добавив гиперссылку внутри вызовет проблемы - если вы нажмете на гиперссылку, кнопка на самом деле не нажата, поэтому вы не получите команду, если вы нажмете на область без гиперссылки, все будет хорошо...

Если вы действительно do хочу, чтобы гиперссылка была там... Вы можете установить IsHitTestVisible из окружающего textblock в false.

например:

<TextBlock IsHitTestVisible="false">
    <Hyperlink NavigateUri="http://www.onet.pl"  >
    <TextBlock Text="{Binding}" />
</TextBlock>

это потому, что вы связываете команду в другом контексте данных.

в StackPanel вы связываете команду в текущем контексте данных, который, вероятно, является вашей моделью представления, содержащей команду.

в ListView вы привязываете команду к другому контексту данных, который является текущим элементом списка, который, я считаю, является объектом ссылки, который, вероятно, не содержит команду.

Если вы хотите, чтобы команда имела такое же поведение, как в ваш StackPanel, просто дайте имя представлению списка и сделайте привязку к контексту данных ListView вместо контекста данных ListViewItem.

<ListView x:Name="linksListView" ItemsSource="{Binding Links}"> 
    <ListView.ItemTemplate>
        <DataTemplate>
            <Border>
                <Button Command="{Binding DataContext.GetOddsCommand, ElementName=linksListView}"
                        CommandParameter="{Binding DataContext, ElementName=linksListView}">
                    <TextBlock>
                        <Hyperlink NavigateUri="http://www.onet.pl" >
                            <TextBlock Text="{Binding}" />
                        </Hyperlink>
                    </TextBlock>
                </Button>
            </Border>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>