选择数据模板中的控件时获取行详细信息

问题描述

我正在构建一个 WPF 应用程序并尽可能地坚持 MVVM 模式。我有一个列表框,其中包含一个包含 TextBlockButton 的数据模板。如果单击数据模板中的按钮,它不会选择整行,因此我不知道它属于哪一行。我想获取整个对象并将其绑定到视图模型中的属性。我可以得到一些帮助或解决方法吗,请坚持 mvvm 模式。

带有项目模板的列表框

<telerik:RadListBox Width="200" Height="150" HorizontalAlignment="Left" Margin="10" ItemsSource="{Binding listofsupplierInvoices}"  
                    SelectedItem="{Binding SelectedsupplierInvoice,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
   <telerik:RadListBox.ItemTemplate>
      <DataTemplate>
         <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" >
            <TextBlock Text="{Binding InvoiceNumber}" HorizontalAlignment="Left" Margin="5" ></TextBlock>
            <telerik:RadButton  Height="20"  >
               <telerik:RadButton.Content>
                  <Image Source="/ImageResources/Misc/delete.png" Stretch="Fill" />
               </telerik:RadButton.Content>
            </telerik:RadButton>
         </StackPanel>
      </DataTemplate>
   </telerik:RadListBox.ItemTemplate>
</telerik:RadListBox>

它在视图中的样子:

ListBox with an item that contains a button.

解决方法

据我了解你的代码,按钮对应一个删除命令,意思是你要删除与按钮关联的项目。在这种情况下,选择可能不需要更改,您只需将当前项目传递给删除命令即可。

向您的视图模型添加 Delete 命令,如下所示:

public class MyViewModel : ViewModelBase
{
   public MyViewModel()
   {
      Delete = new DelegateCommand(ExecuteDelete,CanExecuteDelete);

      // ...other code.
   }

   public ICommand Delete { get; }

   private void ExecuteDelete(object obj)
   {
      var invoiceItem = (InvoiceItem) obj;

      // Use this only if you need the item to be selected.
      // SelectedSupplierInvoice = invoiceItem;

      // ...your delete logic.
   }

   private bool CanExecuteDelete(object obj)
   {
      // ...your can execute delete logic.
   }

   // ...other code.
}

注意我引入了InvoiceItem作为物品类型,因为我不知道你的物品类型,简单地调整它。 Delete 命令获取作为参数传递的当前项目。如果您始终可以删除该项目,则无需选择它,因为它之后就消失了。

否则,取消注释该行,以便将 SelectedSupplierInvoice 设置为项目,如果您已正确实现 INotifyPropertyChanged 或从 {{3} 派生,该项目将通过双向绑定自动更新用户界面} 暴露了 RaisePropertyChangedOnPropertyChanged 方法,例如:

private InvoiceItem _selectedSupplierInvoice;
public InvoiceItem SelectedSupplierInvoice
{
   get => _selectedSupplierInvoice;
   set
   {
      if (_selectedSupplierInvoice == value)
         return;

      _selectedSupplierInvoice = value;
      RaisePropertyChanged();
   }
}

在您的 XAML 中,将按钮连接到 DeleteDataContext 上的 RadListBox 命令。

<telerik:RadButton  Height="20"
                    Command="{Binding DataContext.Delete,RelativeSource={RelativeSource AncestorType={x:Type telerik:RadListBox}}}"
                    CommandParameter="{Binding}">
   <telerik:RadButton.Content>
      <Image Source="/ImageResources/Misc/delete.png" Stretch="Fill" />
   </telerik:RadButton.Content>
</telerik:RadButton>