2013-11-14 17 views
5

Sto lavorando su un'applicazione WPF con .NET framework 4.0DataGrid WPF Virtualizzazione e Command CanExecute

Ho un problema con un DataGrid: ogni linea ha ottenuto 2 comandi:

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

e non v'è lo stesso comando per MoveDown (può eseguire controllo se la linea non è l'ultimo)

E il 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> 

Se virtualizzo la mia griglia con EnableRowVirtualization su true, ho qualche problema se scorrono verso il basso (le prime righe non sono più visibili) e poi lo scorrimento verso l'alto, a volte il pulsante moveup della prima riga (normalmente non è possibile move up) è abilitato fino a quando clicco su DataGrid, e anche il secondo o il terzo è disabilitato, dovrebbe essere abilitato!

se ho impostato EnableRowVirtualization su false, non ho questo problema ...

ho trovato solo un altro post su internet che parlare di questo problema, ma non c'è il DataGrid dalla NET Framework : http://www.infragistics.com/community/forums/t/15189.aspx

avete qualche idea di come posso risolvere il problema?

Grazie in anticipo

Edit: La classe di comando

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

Viene richiamato CanExecute? –

+0

Pubblica il codice della classe 'Command'. –

+0

CanExecute non viene richiamato durante lo scorrimento – Tan

risposta

4

Il problema è quando si scorre con la rotellina del mouse, il CanExecute non viene chiamato.

Creo una proprietà allegata per correggerla e potrebbe essere utilizzata in uno stile.

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

Ed è possibile utilizzare questo attachedProperty in uno stile come questo:

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

Grazie Eran Otzap per farmi vedere il motivo per cui ho avuto questo problema!