ListView 中的 WPF 按钮在 ViewModel 中看不到命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14056939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 06:47:40  来源:igfitidea点击:

WPF button in ListView can not see command in ViewModel

c#wpfmvvm

提问by Robert

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

我有 MVVM 应用程序。在视图模型中,我有 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

当我取消注释放置在 StackPanel 命令中的第一个按钮时效果很好。调试器进入 get,然后当我单击命令时,调试器进入 GetOdds 方法。但它不适用于 ListView 中的第二个按钮。看起来第二个按钮看不到 GetOddsCommand,但我不明白为什么

Thanks

谢谢

回答by Blachshma

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 notof the ListViewItem...
You might want to do the same kind of binding for the CommandParameter - Depends on what you're really after.

请注意使用的 DataContext 是 ListView 的而不是ListViewItem 的...
您可能希望为 CommandParameter 执行相同类型的绑定 - 取决于您真正想要的是什么。

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 dowant the hyperlink there... You can set the IsHitTestVisibleof the surrounding textblock to false.

如果你真的想要的超级链接那里......你可以设置IsHitTestVisible周围文本块的假。

e.g.:

例如:

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

回答by Ucodia

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.

在 StackPanel 中,您正在当前数据上下文中绑定命令,这可能是您持有命令的视图模型。

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.

在 ListView 中,您将命令绑定在不同的数据上下文上,该数据上下文是当前列表项,我认为它是一个可能不包含该命令的 Link 对象。

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.

如果您希望命令具有与 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>