冒泡WPF Datagrid Item事件

时间:2012-05-29 09:31:36

标签: wpf events datagrid

我有一个带有ItemsSource ObservableCollection(OC)对象的数据网格。当一个项目的属性发生变化时,我想在OC本身上工作。

E.g。我有一个批准上传到我们数据库的项目。但是,我需要遍历OC以检查集合中是否存在已经符合设置标准的其他项目,这样我实际上可能不必上传所选项目。

在datagrid上,当我勾选项目的复选框时,它将更改项目的布尔值(例如“IsToUpload”),并且应该在属性更改时触发事件。

我假设我需要将我的事件通知“冒泡”到datagrid / mainwindow类,然后我可以在OC上工作。我怎么能这样做,如果这不是正确的方法,我该怎么办?

我遵循Aran Mulholland的类结构动态地为我的行着色:Coloring WPF DataGridRows one by one

所以我的班级结构大致如下:

MainWindow -> DataGrid 
   -> ObservableCollection<ItemObjectViewModel:NotificationObject>

ItemObject : INotifyPropertyChanged //this class is where I 
    //store my item variables. It is referenced through properties 
    //in the ItemObjectViewModel.

1 个答案:

答案 0 :(得分:0)

事件冒泡\路由等适用于visual \ logical树中的依赖项对象。您的NotificationObject不是依赖对象,也不是托管在可视化树中....我们在可视树中拥有的是复选框(绑定到NotificationObject)。

非MVVM

在您的DataGrid中,您必须使用某些标识标记您的复选框,然后在数据网格级别使用ButtonBase.Click =“”事件,该事件将针对任何基于按钮的eleemnt(例如按钮,menuitems,在数据网格的整个可视树中单击的togglebuttons,checkboxes,radioboxes,comboboxes。

在处理程序中验证e.OriginalSource是否为复选框,并且其Tag与我们在数据网格的XAML中设置的标识值相同。这样我们就知道点击了CheckBox。

<强> E.g。

        <DataGrid AutogenerateColumns="False"
                  ItemsSource="{Binding NotificationObjectCollection}"
                  ButtonBase.Clicked="OnNotificationCheckBoxClicked">
            <DataGrid.Columns>
                 <DataGridCheckBoxColumn Binding="{Binding IsClicked}"
                                         Header="Click?">
                     <DataGridCheckBoxColumn.ElementStyle> 
                         <Style TargetType="{x:Type CheckBox}">
                             <Setter Property="Tag" Value="IsClickCheckBox" />
                         </Style>                          
                     </DataGridCheckBoxColumn.ElementStyle>
                 </DataGridCheckBoxColumn>   
            </DataGrid.Columns>
        </DataGrid>  


  private void OnNotificationCheckBoxClicked
            (object sender, RoutedEventArgs e)
  {
        if (e.OriginalSource is CheckBox)
        {
              if (((CheckBox)e.OriginalSource).Tag == "IsClickCheckBox")
              {
                    var notificationObject
                        = ((CheckBox)e.OriginalSource).DataContext 
                             as NotificationObject;

                    if (notificationObject.IsClicked) { } 
                    else  { }  
              }
         }
  }  

<强> MVVM

MVVM在视觉中通知祖先对象的唯一方法是使用Command执行,因为底层NotificationObject被检查(调用setter)我们执行提供给{{1}的命令}。

为此,请使用基于 NotificationObject RelayCommand 的弱引用(在互联网上提供)。

添加新的DelegateCommand构造函数

NotificationObject

使用通知对象

 private ICommand _isClickedCommand;
 public NotificationObject(ICommand isClickedCommand)
 {
     _isClickedCommand = isClickedCommand;
 }


 private bool _isClicked;
 public bool IsClicked
 {
    get
    {
         return _isClicked;
    }
    set
    {
        if (_isClicked != value)
        {
           _isClicked = value;
           OnPropertyChanged("IsClicked");
           isClickedCommand.Execute(this);
        }
    }
 } 

您还可以使用'RoutedCommand'

在非MVVM方案中实现基于 public class ItemObjectViewModel { private DelegateCommand<NotificationObject> _notificationObjectClickedCommand = new DelegateCommand<NotificationObject>( OnNotificationObjectCommandExecute); .... private void PopulateCollection() { NotificationObjectCollection = new ObservableCollection<NotificationObject>(); NotificationObjectCollection.Add( new NotificationObject(_notificationObjectClickedCommand)); } private void OnNotificationObjectCommandExecute( NotificationObject notificationObject) { if (notificationObject.IsClicked) { } else { } } } 的行为

如果这有帮助,请告诉我......