5

我正在使用框架 .NET 4.0 开发 WPF 应用程序

我对 DataGrid 有疑问:每行都有 2 个命令:

public ICommand MoveUpOrderPipeCommand
{
     get
     {
         if (_moveUpOrderPipeCommand == null)
         {
              _moveUpOrderPipeCommand = new Command<OrderPipeListUIModel>(OnMoveUpOrderPipe, CanMoveUpOrderPipe);
         }
                return _moveUpOrderPipeCommand;
      }
}

private bool CanMoveUpOrderPipe(OrderPipeListUIModel orderPipe)
{
     if (OrderPipes == null || !OrderPipes.Any() || OrderPipes.First() == orderPipe)
          return false;
     return true;
}

并且 MoveDown 也有相同的命令(可以执行检查该行是否不是最后一行)

和 DataGrid :

<DataGrid Grid.Row="1" IsReadOnly="True" ItemsSource="{Binding OrderPipes}" SelectionMode="Extended">
   <DataGrid.Columns>
      <DataGridTextColumn Header="Diam. (mm)" Binding="{Binding Diameter}" Width="120">    </DataGridTextColumn>
      <DataGridTextColumn Header="Lg. (m)" Binding="{Binding Length}" Width="120"></DataGridTextColumn>
      <DataGridTextColumn Header="Ep. (mm)" Binding="{Binding Thickness}" Width="120"></DataGridTextColumn>
      <DataGridTextColumn Header="Ondulation" Binding="{Binding Ripple}" Width="120"></DataGridTextColumn>
      <DataGridTemplateColumn>
         <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
               <StackPanel Orientation="Horizontal">
                  <Button Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.MoveUpOrderPipeCommand}" CommandParameter="{Binding}">
                  </Button>
               </StackPanel>
            </DataTemplate>
         </DataGridTemplateColumn.CellTemplate>
      </DataGridTemplateColumn>
   </DataGrid.Columns>
</DataGrid>

如果我使用 EnableRowVirtualization 将我的网格虚拟化为 true,我会遇到一些麻烦,如果我滚动到底部(第一行不再可见)然后滚动回顶部,有时第一行的按钮向上移动(通常不能向上移动) 是启用的,直到我单击 DataGrid,并且第二个或第三个是禁用的,应该启用!

如果我将 EnableRowVirtualization 设置为 false,我就没有这个问题...

我只在互联网上找到另一篇谈论这个问题的帖子,但没有来自 .net 框架的 dataGrid:http: //www.infragistics.com/community/forums/t/15189.aspx

你知道我该如何解决吗?

先感谢您

编辑:命令类

public class Command<T> : ICommand
{
    private readonly Action<T> _execute;
    private readonly Func<T, bool> _canExecute;

    public Command(Action<T> execute) : this(execute, null)
    {
    }

    public Command(Action<T> execute, Func<T, bool> canExecute)
    {
       if (execute == null)
          throw new ArgumentNullException("execute", "Le délégué execute ne peut pas être nul");

       this._execute = execute;
       this._canExecute = canExecute;
    }

    public event EventHandler CanExecuteChanged
    {
       add
       {
          CommandManager.RequerySuggested += value;
       }
       remove
       {
          CommandManager.RequerySuggested -= value;
       }
    }

    public bool CanExecute(object parameter)
    {
       return (_canExecute == null) ? true : _canExecute((T)parameter);
    }

    public void Execute(object parameter)
    {
       _execute((T)parameter);
    }
 }
4

1 回答 1

5

问题是当您使用鼠标滚轮滚动时,不会调用 canExecute。

我创建了一个 AttachedProperty 来纠正这个问题,它可以用于一种风格。

public static readonly DependencyProperty CommandRefreshOnScrollingProperty = DependencyProperty.RegisterAttached(
            "CommandRefreshOnScrolling", 
            typeof(bool), 
            typeof(DataGridProperties), 
            new FrameworkPropertyMetadata(false, OnCommandRefreshOnScrollingChanged));

private static void OnCommandRefreshOnScrollingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
      var dataGrid = d as DataGrid;
      if (dataGrid == null)
      {
          return;
      }
      if ((bool)e.NewValue)
      {
         dataGrid.PreviewMouseWheel += DataGridPreviewMouseWheel;
      }
}
private static void DataGridPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
     CommandManager.InvalidateRequerySuggested();
}

你可以像这样使用这个 attachProperty:

    <Setter Property="views:DataGridProperties.CommandRefreshOnScrolling" Value="True"></Setter>

感谢 Eran Otzap 告诉我为什么我会遇到这个问题!

于 2013-12-02T09:38:54.693 回答