Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF button in ListView can not see command in ViewModel

Tags:

c#

mvvm

wpf

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

I have MVVM application. In viewmodel I have GetOddsCommand:

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

private void GetOdds()
{

}

When I uncomment first button placed in StackPanel command works good. Debugger step into get and then when I click command Debugger step into GetOdds method. But it doesn't work in second button which is in the ListView. Looks like second button cannot see GetOddsCommand, but I don't understand why

Thanks

like image 515
Robert Avatar asked Dec 27 '12 15:12

Robert


2 Answers

Putting a button and inside it a Hyperlink doesn't make much sense... What do you expect to happen when you click on the hyperlink?
Anyways, the following code will cause your command to be called:

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

Notice the DataContext used is that of the ListView not of the ListViewItem...
You might want to do the same kind of binding for the CommandParameter - Depends on what you're really after.

Now, adding the hyperlink inside will cause problems - if you click on the Hyperlink the button isn't really clicked so you won't get the command, if you click on an area without the hyperlink everything will be fine...

If you really do want the hyperlink there... You can set the IsHitTestVisible of the surrounding textblock to false.

e.g.:

<TextBlock IsHitTestVisible="false">
    <Hyperlink NavigateUri="http://www.onet.pl"  >
    <TextBlock Text="{Binding}" />
</TextBlock>
like image 83
Blachshma Avatar answered Oct 01 '22 13:10

Blachshma


It is because you are binding the command in a different data context.

In the StackPanel, you are binding the command in the current data context which is probably your view model holding the command.

In the ListView, you are binding the command on a different data context which is the current list item which I believe is a Link object that probably does not hold the command.

If you want the command to have the same behavior as in your StackPanel, just give a name to the list view and make the binding on the ListView data context instead of ListViewItem data context.

<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>
like image 37
Ucodia Avatar answered Oct 01 '22 15:10

Ucodia