2

我的父 ViewModel 中有一个 ObservableCollection,我想在父视图中显示它。所以我定义了一个子 View 和一个子 ViewModel 处理按钮点击。如何在不丢失我已经设置的 RelayCommands 以进行按钮单击处理的情况下将 ObservableCollection 中的每个项目获取到相应的子 ViewModel 中?

在我的父 View Code-Behind 中,我唯一要做的就是将 DataContext 设置为适当的 ViewModel:

DataContext = new ParentViewModel();

在我的父视图 XAML 中,我定义了一个 ListBox 来显示我的子视图的 DataTemplate:

<ListBox
  ItemsSource="{Binding Path=Items}">
  <ListBox.ItemTemplate>
    <DataTemplate DataType="{x:Type vm:ChildViewModel}">
      <views:ChildView Width="auto" />
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

现在在我的 ChildView 中,我有几个 TextBlocks 显示绑定数据和按钮,它们应该在 ObservableCollection 中指定的路径中执行文件:

<TextBlock
  Text="{Binding Path=Title}" />
...
<Button
  Content="Start exe"
  Tag="{Binding Path=ExePath}">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
      <i:InvokeCommandAction Command="{Binding Path=OnButtonClicked}" />
    </i:EventTrigger>
  </i:Interaction.Triggers>
</Button>

Child ViewModel 持有 RelayCommands 来处理 Button 点击​​事件:

private RelayCommand onButtonClicked;
public ICommand OnButtonClicked
{
  get
  {
    return onButtonClicked ??
      (onButtonClicked =
      new RelayCommand(ObeyOnButtonClicked, CanObeyOnButtonClicked));
  }
}
private void ObeyOnButtonClicked()
{
  ... //Path conversion
  Process.Start(pathToExe);
}
private bool CanObeyOnButtonClicked()
{
  return true;
}

现在,在我的子视图的代码隐藏中,当我添加

DataContext = new SampleItemViewModel();

对于构造函数,按钮单击已处理,但文本框全部为空。当我删除此行时,文本框已正确填充,但未处理按钮单击。

如何让这两个功能都工作?

编辑:

父视图模型:

private ObservableCollection<Item> items;
public ObservableCollection<Item> Items
{
  get { return items; }
  set
  {
    items= value;
    OnPropertyChanged("Items");
  }
}

... //Filling the Collection in Constructor

ChildViewModel 仅包含上面提到的按钮单击处理程序。

编辑:

我现在尝试了几件事,但我不知道如何将命令从 ChildView 绑定到我的 ChildViewModel 而不将我的 ChildView 的 DataContext 设置为我的 ChildViewModel

4

1 回答 1

1

您可以删除事件触发器,因为 Button 具有 Command 属性。

<TextBlock Text="{Binding Path=Title}" />
...
<Button
  Content="Start exe"
  Tag="{Binding Path=ExePath}"
  Command="{Binding Path=OnButtonClicked}"
>
</Button>

并设置 DataContext :

<ListBox
  ItemsSource="{Binding Path=Items}">
  <ListBox.ItemTemplate>
    <DataTemplate DataType="{x:Type vm:ChildViewModel}">
      <views:ChildView Width="auto" DataContext="{Binding}" />
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>
于 2013-03-22T11:53:01.087 回答