将DataTemplate中的按钮绑定到窗体的ViewModel中

Chr*_*cht 26 c# data-binding wpf xaml mvvm

我的问题类似于这个问题中描述的问题:
DataTemplate中的WPF MVVM按钮控件绑定

这是我的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>
Run Code Online (Sandbox Code Playgroud)

它只是一个ListBox绑定到ObservableCollection<string>命名CommandSets(在ViewModel中).
此绑定有效(它显示集合中每个项目的按钮).

现在我想将按钮绑定到一个命令(FireCommand),该命令也在ViewModel中.
这是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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 按钮在里面ListBox,所以它只"知道" ListBox(ObservableCollection在这种情况下)的绑定,而不是主窗口的绑定
  • 我正在尝试绑定到主窗口的主ViewModel中的命令(按钮不"知道")

命令本身是绝对正确的,因为当我把按钮之外ListBox(见上面的XAML的例子),则执行绑定的工作和命令.

显然,我"只是"需要告诉按钮绑定到窗体的主ViewModel.
但是我无法弄清楚正确的XAML语法.

我尝试了几种谷歌搜索后发现的方法,但没有一种方法适合我:

<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}}}" />
Run Code Online (Sandbox Code Playgroud)

有人可以请:

  1. 给我正确的XAML来绑定ListBox窗体中的命令内的按钮MainViewModel
  2. 请指出一个链接,其中这个高级绑定的东西以WPF/MVVM初学者可以理解的方式解释?
    我觉得我只是在复制和粘贴神秘的XAML咒语,到目前为止我没有任何线索(并且找不到任何好的文档)我怎么会自己弄明白我需要哪些情况RelativeSource或者StaticResource等等而不是"正常"的约束.

H.B*_*.B. 62

它的:

{Binding DataContext.FireCommand,
         RelativeSource={RelativeSource AncestorType=ListBox}}
Run Code Online (Sandbox Code Playgroud)

除非你实际上DataContext一直在改变,否则不需要走到root ,但是因为ListBox似乎绑定到主VM上的属性,这应该足够了.

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


此处还有关于如何构造绑定的简短说明:绑定由Path相对于该的相对组成,默认情况下,是当前的DataContext.可以明确设置的来源是:Source,ElementName&RelativeSource.设置其中任何一个将覆盖DataContextas .

因此,如果您使用类似的RelativeSource并希望访问DataContext该级别的某些内容,则DataContext需要在该级别中显示Path.


Tan*_*pps 5

大多数人可能认为这无关,但此搜索只是搜索数据模板内控件的数据绑定命令的 3 个结果之一 - 因为它与 Xamarin Forms 相关。所以,也许它现在会对某人有所帮助。

像我一样,您可能想知道如何在 BindableLayout 内绑定命令。感谢 jesulink2514 在 Xamarin 论坛上回答这个问题,由于所有评论,它可能被许多人忽视。这是他的解决方案,但我添加了以下链接:

<ContenPage x:Name="MainPage">
<ListView Grid.Row="1"
              ItemsSource="{Binding Customers}"
              VerticalOptions="Fill"
              x:Name="ListviewCustomer">
      <ListView.ItemTemplate>
        <DataTemplate>
      <Label Text="{Binding Property}"/>
          <Button Command="{Binding BindingContext.ItemCommand, Source={x:Reference MainPage}}" 
                         CommandParameter="{Binding .}">Click me</Button>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
</ContentPage>
Run Code Online (Sandbox Code Playgroud)

https://forums.xamarin.com/discussion/comment/217355/#Comment_217355