将 DataTemplate 中的按钮绑定到表单的 ViewModel 中的命令

本文介绍了将 DataTemplate 中的按钮绑定到表单的 ViewModel 中的命令的处理方法,对大家解决问题具有一定的参考价值

问题描述

我的问题与此问题中描述的问题相似:
DataTemplate 中的 WPF MVVM 按钮控件绑定

My problem is similar to the one described in this question:
WPF MVVM Button Control Binding in DataTemplate

这是我的 XAML:

<Window x:Class="MissileSharp.Launcher.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MissileSharp Launcher" Height="350" Width="525">
    <Grid>
        <!-- when I put the button here (outside the list), the binding works -->
        <!--<Button Content="test" Command="{Binding Path=FireCommand}" />-->
        <ListBox ItemsSource="{Binding CommandSets}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <!-- I need the button here (inside the list), and here the binding does NOT work -->
                    <Button Content="{Binding}" Command="{Binding Path=FireCommand}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

它只是一个 ListBox,绑定到一个名为 CommandSetsObservableCollection(在 ViewModel 中).
此绑定有效(它为集合中的每个项目显示一个按钮).

It's just a ListBox, bound to an ObservableCollection<string> named CommandSets (which is in the ViewModel).
This binding works (it displays a button for each item in the collection).

现在我想将按钮绑定到一个命令 (FireCommand),该命令也在 ViewModel 中.
这是 ViewModel 的相关部分:

Now I want to bind the button to a command (FireCommand), which is also in the ViewModel.
Here's the relevant part of the ViewModel:

public class MainWindowViewModel : INotifyPropertyChanged
{
    public ICommand FireCommand { get; set; }
    public ObservableCollection<string> CommandSets { get; set; }

    public MainWindowViewModel()
    {
        this.FireCommand = new RelayCommand(new Action<object>(this.FireMissile));
    }

    private void FireMissile(Object obj)
    {
        System.Windows.MessageBox.Show("fire");
    }
}

此按钮的绑定不起作用.
根据我从上面链接的 问题 中了解到的,绑定不起作用,因为:
(如果我错了,请纠正我)

The binding of this button does NOT work.
From what I've understood from the question I linked above, the binding doesn't work because:
(correct me if I'm wrong)

  • 按钮在 ListBox 内部,所以它只知道"ListBox 的绑定(在本例中为 ObservableCollection),但不是主窗口的绑定
  • 我正在尝试绑定到主窗口的主 ViewModel 中的命令(按钮不知道")
  • The button is inside the ListBox, so it only "knows" the binding of the ListBox (the ObservableCollection, in this case), but not the binding of the main window
  • I'm trying to bind to a command in the main ViewModel of the main window (which the button doesn't "know")

命令本身绝对是正确的,因为当我将按钮放在ListBox(参见上面的XAML示例)时,绑定有效,命令是执行.

The command itself is definitely correct, because when I put the button outside the ListBox (see the XAML above for an example), the binding works and the command is executed.

显然,我只需要"告诉按钮绑定到表单的主 ViewModel.
但我无法找出正确的 XAML 语法.

我尝试了一些谷歌搜索后发现的方法,但没有一个对我有用:

I tried several approaches that I found after some googling, but none of them worked for me:

<Button Content="{Binding}" Command="{Binding RelativeSource={RelativeSource Window}, Path=DataContext.FireCommand}" />

<Button Content="{Binding}" Command="{Binding Path=FireCommand, Source={StaticResource MainWindow}}" />

<Button Content="{Binding}" Command="{Binding Path=FireCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />

有人可以吗:

  1. 给我适当的 XAML 以将 ListBox 内的按钮绑定到表单 MainViewModel 中的命令?
  2. 指向一个链接,其中以 WPF/MVVM 初学者可以理解的方式解释了这种高级绑定内容?
    我觉得我只是在复制和粘贴神秘的 XAML 咒语,到目前为止我没有任何线索(并且找不到任何好的文档)我如何自己弄清楚在哪些情况下我需要 RelativeSourceStaticResource 或其他任何东西,而不是正常"绑定.
  1. give me the proper XAML to bind the button inside the ListBox to a command in the form's MainViewModel?
  2. point me to a link where this advanced binding stuff is explained in a way that a WPF/MVVM beginner can understand?
    I'm feeling like I'm just copying and pasting arcane XAML incantations, and so far I don't have any clue (and can't find any good documentation) how I would figure out by myself in which cases I'd need RelativeSource or StaticResource or whatever instead of a "normal" binding.

推荐答案

It's:

{Binding DataContext.FireCommand,
         RelativeSource={RelativeSource AncestorType=ListBox}}

除非您沿途实际更改了 DataContext,否则无需走到根目录,但由于 ListBox 似乎绑定到主 VM 上的属性,因此应该够了.

No need to walk up to the root unless you actually change the DataContext along the way, but as the ListBox seems to bind to a property on the main VM this should be enough.

我唯一推荐阅读的是数据绑定概述Binding 文档(包括其属性).

The only thing i recommend reading is the Data Binding Overview, and the Binding class documentation (including its properties).

这里还有一个关于如何构建绑定的简短解释:一个绑定由一个 source 和一个相对于那个 Path 组成>source,默认情况下 source 是当前的 DataContext.可以显式设置的源有:SourceElementName &相对源.设置其中任何一个都会将 DataContext 覆盖为 source.

Also here is a short explanation on how bindings are constructed: A binding consists of a source and a Path relative to that source, by default the source is the current DataContext. Sources that can be set explicitly are: Source, ElementName & RelativeSource. Setting any of those will override the DataContext as source.

因此,如果您使用 source 之类的 RelativeSource 并希望在该级别访问 DataContext 中的某些内容,DataContext 需要出现在Path中.

So if you use a source like RelativeSource and want to access something in the DataContext on that level the DataContext needs to appear in the Path.

这篇关于将 DataTemplate 中的按钮绑定到表单的 ViewModel 中的命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2

admin_action_{$_REQUEST[‘action’]}

do_action( "admin_action_{$_REQUEST[‘action’]}" )动作钩子::在发送“Action”请求变量时激发。Action Hook: Fires when an ‘action’ request variable is sent.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$_REQUEST['action']引用从GET或POST请求派生的操作。源码(Source)更新版本源码位置使用被使用2.6.0 wp-admin/admin.php:...

日期:2020-09-02 17:44:16 浏览:1179

admin_footer-{$GLOBALS[‘hook_suffix’]}

do_action( "admin_footer-{$GLOBALS[‘hook_suffix’]}", string $hook_suffix )操作挂钩:在默认页脚脚本之后打印脚本或数据。Action Hook: Print scripts or data after the default footer scripts.目录锚点:#说明#参数#源码说明(Description)钩子名的动态部分,$GLOBALS['hook_suffix']引用当前页的全局钩子后缀。参数(Parameters)参数类...

日期:2020-09-02 17:44:20 浏览:1075

customize_save_{$this->id_data[‘base’]}

do_action( "customize_save_{$this-&gt;id_data[‘base’]}", WP_Customize_Setting $this )动作钩子::在调用WP_Customize_Setting::save()方法时激发。Action Hook: Fires when the WP_Customize_Setting::save() method is called.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_data...

日期:2020-08-15 15:47:24 浏览:817

customize_value_{$this->id_data[‘base’]}

apply_filters( "customize_value_{$this-&gt;id_data[‘base’]}", mixed $default )过滤器::过滤未作为主题模式或选项处理的自定义设置值。Filter Hook: Filter a Customize setting value not handled as a theme_mod or option.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_date['base'],指的是设置...

日期:2020-08-15 15:47:24 浏览:908

get_comment_author_url

过滤钩子:过滤评论作者的URL。Filter Hook: Filters the comment author’s URL.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/comment-template.php:32610...

日期:2020-08-10 23:06:14 浏览:939

network_admin_edit_{$_GET[‘action’]}

do_action( "network_admin_edit_{$_GET[‘action’]}" )操作挂钩:启动请求的处理程序操作。Action Hook: Fires the requested handler action.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$u GET['action']引用请求的操作的名称。源码(Source)更新版本源码位置使用被使用3.1.0 wp-admin/network/edit.php:3600...

日期:2020-08-02 09:56:09 浏览:886

network_sites_updated_message_{$_GET[‘updated’]}

apply_filters( "network_sites_updated_message_{$_GET[‘updated’]}", string $msg )筛选器挂钩:在网络管理中筛选特定的非默认站点更新消息。Filter Hook: Filters a specific, non-default site-updated message in the Network admin.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分$_GET['updated']引用了非默认的...

日期:2020-08-02 09:56:03 浏览:873

pre_wp_is_site_initialized

过滤器::过滤在访问数据库之前是否初始化站点的检查。Filter Hook: Filters the check for whether a site is initialized before the database is accessed.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/ms-site.php:93910...

日期:2020-07-29 10:15:38 浏览:838

WordPress 的SEO 教学:如何在网站中加入关键字(Meta Keywords)与Meta 描述(Meta Description)?

你想在WordPress 中添加关键字和meta 描述吗?关键字和meta 描述使你能够提高网站的SEO。在本文中,我们将向你展示如何在WordPress 中正确添加关键字和meta 描述。为什么要在WordPress 中添加关键字和Meta 描述?关键字和说明让搜寻引擎更了解您的帖子和页面的内容。关键词是人们寻找您发布的内容时,可能会搜索的重要词语或片语。而Meta Description则是对你的页面和文章的简要描述。如果你想要了解更多关于中继标签的资讯,可以参考Google的说明。Meta 关键字和描...

日期:2020-10-03 21:18:25 浏览:1761

谷歌的SEO是什么

SEO (Search Engine Optimization)中文是搜寻引擎最佳化,意思近于「关键字自然排序」、「网站排名优化」。简言之,SEO是以搜索引擎(如Google、Bing)为曝光媒体的行销手法。例如搜寻「wordpress教学」,会看到本站的「WordPress教学:12个课程…」排行Google第一:关键字:wordpress教学、wordpress课程…若搜寻「网站架设」,则会看到另一个网页排名第1:关键字:网站架设、架站…以上两个网页,每月从搜寻引擎导入自然流量,达2万4千:每月「有机搜...

日期:2020-10-30 17:23:57 浏览:1319