2016-09-22 148 views
0

我制作了带有MVVM模式的UWP应用程序(我认为是这样:)) 我的应用程序有列表框的数据模板。 列表框在View.xaml:DataTemplate中的绑定命令

<ListBox x:Name="lbMySongs" ItemsSource="{Binding Path=MySongs}" ItemTemplate="{StaticResource lbSongsTemplate}" Grid.Row="1"> 
     <ListBox.ItemContainerStyle> 
      <Style TargetType="ListBoxItem"> 
       <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
      </Style> 
     </ListBox.ItemContainerStyle> 
</ListBox/> 

DateTemplate资源:

 <DataTemplate x:Key="lbSongsTemplate"> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="auto"/> 
       <ColumnDefinition Width="auto"/> 
       <ColumnDefinition Width="*"/> 
       <ColumnDefinition Width="auto"/> 
       <ColumnDefinition Width="auto"/> 
      </Grid.ColumnDefinitions> 
      <TextBlock Text="{Binding Path=Artist}" Grid.Column="0"/> 
      <TextBlock Text=" - " Grid.Column="1"/> 
      <TextBlock Text="{Binding Path=Title}" Grid.Column="2"/> 
      //Here i bind command, but it's not binding cos ItemsSource have no command. ViewModel have this command. 
      <Button Command="{Binding Path=DownloadCommand}" Content="{Binding Path=Query}"/> 
      <TextBlock Text="{Binding Duration}" Grid.Column="5" HorizontalAlignment="Right"/> 
     </Grid> 
     </DataTemplate> 

需要设置的DataContext此按钮。 我在ViewModel中的命令。例如:

class ViewModel 
{ 
    ... 
    public RelayCommand DownloadCommand { get; set; } 
    public ObservableCollection<SomeClass> MySongs { get; set; } 
    ... 
} 

我的问题:DataTemplate有ItemsSource = ViewModel.MySongs。但是“DownloadCommand”在ViewModel中。 我在DataTemplate中为我的按钮设置绑定到DownloadCommand?

+0

在键盘上选择按钮 - >点击'F4'你会看到属性 - >搜索命令 - >点击文本框后的小灰点按钮,从绑定窗口中选择创建绑定 - >选择你的'DownloadCommand' - > Voila – AVK

回答

2

尝试使用:

<Button Command="{Binding Path=DataContext.DownloadCommand, ElementName=lbMySongs}" 
     CommandParameter="{Binding}" 
     Content="{Binding Path=Query}"/> 

,并更改

public RelayCommand DownloadCommand { get; set; } 

public RelayCommand<SomeClass> DownloadCommand { get; set; } 
... 
DownloadCommand = new RelayCommand<SomeClass>(DownloadExecute); 
... 
private voir DownloadExecute(SomeClass item) 
{ 
    ... 
} 
2

使用RelativeSource结合说你要绑定ListBox.DataContext.DownloadCommand

<Button Command="{Binding Path=DataContext.DownloadCommand, 
          RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" 
     Content="{Binding Path=Query}"/> 

它像这往往常见的做法是还绑定CommandParameter到项目知道项目的命令上执行:

<Button Command="{Binding Path=DataContext.DownloadCommand, 
          RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" 
     CommandParameter="{Binding }" 
     Content="{Binding Path=Query}" /> 

你也可以使用一个ElementName约束力,但你必须给你的ListBox a要在您的DataTemplate中指定的名称,并且我个人不喜欢在我的DataTemplates中硬编码ElementName。如果您更改了某个名称,或者想要在另一个ListBox中使用DataTemplate,则会发现并修复它令人讨厌。

+2

这不适用于UWP,因为FindAncestor不支持RelativeSource绑定 – ndonohoe

+0

@ndonohoe Ahhhh我忘了UWP。快速谷歌搜索“UWP FindAncestor”导致[此StackOverflow后](http://stackoverflow.com/a/32865846/302677)其中包含建议使用DependencyProperty提供这种行为。我个人会尝试设置一些像这样的自定义来代替FindAncestor功能,而不是使用ElementName,尽管如果使用'ElementName'失败的话总是会起作用的。 :) – Rachel