2012-05-29 49 views
0

我有一个数据网格的ItemsSource对象的ObservableCollection(OC)。当一个项目的属性发生变化时,我想在OC上工作。鼓起来WPF Datagrid项目事件

E.g.我有一个项目被批准上传到我们的数据库。但是,我需要通过OC循环检查集合中是否存在已符合设置条件的其他项目,以便我实际上不必上载所选项目。

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

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

我已经按照阿兰穆赫兰的阶级结构动态颜色我行: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. 

回答

0

事件bubling \路由等工程的依赖对象一个视觉\逻辑树。您的NotificationObject不是依赖项对象,也不在可视化树中托管....我们在可视化树中拥有的复选框(绑定到您的NotificationObject)。

非MVVM

在你的DataGrid你会与一些标识标签的复选框,然后使用ButtonBase.Click =“”在数据网格级别事件会为任何click事件处理冒泡任何按钮(例如按钮,菜单项,切换按钮,复选框,单选框,组合框),它们在数据网格的整个可视化树中被点击。

在处理程序中,验证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时),我们执行提供给所述命令NotificationObject

为此,使用基于RelayCommandDelegateCommand弱引用(如在互联网上公布)。

添加新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 { } 
     } 
} 

您也可以实现用“非MVVM情景ICommand基于行为的RoutedCommand '

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

+0

谢谢你的全面解答。我使用了非MVVM示例,并对它进行了调整,以便在确认它是单击的复选框时,我直接修改了ItemObjectViewModel,而不是通过NotificationObject。 – MHTri