我有一个observableCollection,我在视图中使用itemSource循环。 observablecollection中的每个项都包含一个按钮,用于向viewModel发送命令(openSessionCommand)。我的问题是 - 我如何发送和ID回到在itemSource中单击了哪个按钮的viewModel?
<ItemsControl ItemsSource="{Binding AvailableSessions}" Margin="490,181,10.111,39.111">
<ItemsControl.ItemTemplate>
<DataTemplate >
<Border BorderBrush="Black" Background="Gainsboro" BorderThickness="1" Margin="2">
<Grid Background="#FFECECEC">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Command="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}, Path=DataContext.OpenSessionCommand}"
HorizontalAlignment="Left" Margin="10,10,0,0"
VerticalAlignment="Top" Width="243" Height="42">
<TextBlock TextWrapping="Wrap">
<Run Text="{Binding SessionName}"/><LineBreak/>
<Run Text="{Binding Genre}"/><Run Text=" - "/><Run Text="{Binding Tempo}"/>
</TextBlock>
</Button>
<Label Content="{Binding AdminUsername}" HorizontalAlignment="Left"
Margin="10,53,0,0" VerticalAlignment="Top" Width="243" Height="26"/>
<Label Content="{Binding Client1Username}" HorizontalAlignment="Left"
Margin="10,71,0,0" VerticalAlignment="Top" Width="243" Height="25"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer CanContentScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
DelegateCommand:
public class DelegateCommand : ICommand
{
private readonly Action _command;
private readonly Func<bool> _canExecute;
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public DelegateCommand(Action command, Func<bool> canExecute = null)
{
if (command == null)
throw new ArgumentNullException();
_canExecute = canExecute;
_command = command;
}
public void Execute(object parameter)
{
_command();
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute();
}
}
的ICommand:
public ICommand OpenSessionCommand { get
{ return new DelegateCommand(OpenSession); }
}
public void OpenSession()
{
ContinueReceiving = false;
dispatcherTimer.Stop();
Messenger.Default.Send<NavigateMessage>(
new NavigateMessage(SessionViewModel.ViewName, this));
}
答案 0 :(得分:2)
使用CommandParameter。使用{Binding}
将传递被单击的可观察集合中的对象。更多MSDN
<Button Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.OpenSessionCommand}" CommandParemeter="{Binding}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="243" Height="42">
<TextBlock TextWrapping="Wrap">
<Run Text="{Binding SessionName}"/><LineBreak/>
<Run Text="{Binding Genre}"/><Run Text=" - "/>
<Run Text="{Binding Tempo}"/>
</TextBlock>
</Button>
您还需要调整OpenSessionCommand方法签名以接受您的参数,但这取决于您正在使用的Command实现。
<强>更新强>
以下是DelegateCommand的通用实现,它接受一个参数。
public class DelegateCommand<T> : ICommand where T : class
{
private readonly Action<T> _command;
private readonly Func<T, bool> _canExecute;
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public DelegateCommand(Action<T> command, Func<T, bool> canExecute = null)
{
if (command == null)
throw new ArgumentNullException();
_canExecute = canExecute;
_command = command;
}
public void Execute(object parameter)
{
_command(parameter as T);
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute(parameter as T);
}
}
现在,当您定义ICommand时,它应该是这样的:
public ICommand OpenSessionCommand { get { return new DelegateCommand<Button>(OpenSession); } }
public void OpenSession(Button button)
{
ContinueReceiving = false;
dispatcherTimer.Stop();
Messenger.Default.Send<NavigateMessage>(new NavigateMessage(SessionViewModel.ViewName, this));
}
答案 1 :(得分:1)
我在列表框中使用类似的内容与上下文菜单。
<ContextMenu>
<MenuItem Header ="Edit Exercise"
Command="{Binding EditExercise_Command}"
CommandParameter="{Binding SelectedExercise}"
/>
因此,被调用的方法接收我右键单击的练习作为参数。
您可以传递按钮:)