2013-11-14 28 views
5

Pracuję nad aplikacji WPF z .NET Framework 4.0DataGrid WPF Wirtualizacja i poleceń CanExecute

mam problem z DataGrid: każda linia dostał 2 komendy:

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

i istnieje to samo polecenie dla moveDown (można wykonać sprawdzanie czy linia nie jest ostatnim)

A 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> 

Jeśli wirtualizuję moją siatkę, gdy EnableRowVirtualization ma wartość true, mam pewne problemy, jeśli przewijam do dołu (pierwsze linie nie są już widoczne), a następnie przewijam z powrotem do góry, czasami przesuwa się przycisk w pierwszej linii (normalnie nie może do góry) jest włączona, dopóki nie kliknę w DataGrid, a także druga lub trzecia z nich jest wyłączona, powinna być włączona!

Jeżeli ustawić EnableRowVirtualization false, nie mam tego problemu ...

Znalazłem tylko jedno inne stanowisko w Internecie, które mówią o tym problemie, ale nie ma DataGrid z .NET Framework : http://www.infragistics.com/community/forums/t/15189.aspx

Czy masz pojęcie, jak mogę to naprawić?

góry dziękuję

EDIT: klasę polecenia

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

Czy wywoływana jest Twoja CanExecute? –

+0

Napisz kod klasy "Command". –

+0

CanExecute nie jest wywoływana podczas przewijania – Tan

Odpowiedz

4

Problem jest podczas przewijania za pomocą kółka myszy, canExecute nie nazywa.

Tworzę AttachedProperty, aby to poprawić i można go użyć w stylu.

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

I można użyć tej attachedProperty w stylu tak:

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

Dzięki Eran Otzap aby pokazać mi, dlaczego mam tego problemu!