2013-11-14 14 views
5

Tôi đang làm việc trên một ứng dụng WPF với .NET framework 4.0DataGrid WPF Ảo hóa và Command CanExecute

Tôi có một vấn đề với một DataGrid: mỗi dòng có 2 lệnh:

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

Và có lệnh tương tự cho MoveDown (có thể thực hiện kiểm tra nếu dòng không phải là người cuối cùng)

Và 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> 

Nếu tôi ảo hóa lưới của mình bằng EnableRowVirtualization thành true, tôi gặp một số sự cố, nếu tôi cuộn xuống cuối (dòng đầu tiên không hiển thị nữa) và sau đó cuộn trở lại đầu trang, đôi khi nút di chuyển của dòng đầu tiên (normaly không thể di chuyển lên) được kích hoạt cho đến khi tôi bấm vào DataGrid, và cũng là thứ hai hoặc thứ ba là vô hiệu hóa, nên được kích hoạt!

Nếu tôi đặt EnableRowVirtualization false, tôi không có vấn đề này ...

tôi chỉ tìm thấy một bài khác trên internet mà nói về vấn đề này, nhưng không có DataGrid từ khung .net : http://www.infragistics.com/community/forums/t/15189.aspx

Bạn có biết cách khắc phục sự cố không?

Cảm ơn bạn trước

Edit: Các lớp lệnh

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); 
    } 
} 
+0

CanExecute của bạn có được gọi không? –

+0

Đăng mã của lớp 'Command'. –

+0

CanExecute không được gọi khi cuộn – Tan

Trả lời

4

Vấn đề là khi bạn di chuyển với bánh xe chuột, các canExecute không được gọi.

Tôi tạo một AttachedProperty để sửa lỗi này và nó có thể được sử dụng trong một kiểu.

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(); 
} 

Và bạn có thể sử dụng attachedProperty này trong một phong cách như thế này:

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

Cảm ơn Eran Otzap để chỉ cho tôi lý do tại sao tôi đã nhận vấn đề này!