0

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

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

在数据网格上,当我勾选一个项目的复选框时,它将更改项目的布尔值(例如“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.
4

1 回答 1

0

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

非 MVVM

在您的 DataGrid 中,您必须使用一些标识标记您的复选框,然后在数据网格级别使用 ButtonBase.Click="" 事件,该事件将针对任何基于按钮的元素(例如按钮、菜单项、切换按钮、复选框)冒泡的任何单击事件进行处理,单选框,组合框)在数据网格的整个可视化树中被点击。

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

例如

        <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)我们执行提供给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);
        }
    }
 } 

使用通知对象

 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  { }
      }
 }

您还可以ICommand使用“RoutedCommand”在非 MVVM 场景中实现基于行为

让我知道这是否有帮助...

于 2012-05-29T11:00:36.523 回答