2016-09-22 4 views
0

Я сделал приложение UWP с шаблоном MVVM (я так думаю :)) У моего приложения есть шаблон данных для списка. ListBox в 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, и мне лично не нравится жесткий код ElementName в моих DataTemplates. Делает это раздражающим, чтобы найти и исправить, если вы что-то изменили, или хотите использовать DataTemplate в другом ListBox.

+2

Это не работает в UWP, поскольку FindAncestor не поддерживается для привязок RelativeSource – ndonohoe

+0

@ndonohoe Ahhhh Я забыл об этом с помощью UWP. Быстрый поиск в Google «UWP FindAncestor» приводит к [этому сообщению StackOverflow] (http://stackoverflow.com/a/32865846/302677), в котором содержится предложение использовать DependencyProperty для обеспечения такого поведения. Я бы лично попытался настроить что-то подобное, чтобы заменить функциональность FindAncestor, чем использование ElementName, хотя если бы это не сработало с использованием 'ElementName', это всегда срабатывало. :) – Rachel

Смежные вопросы