2013-11-14 7 views
5

Ich bin mit .NET 4.0 FrameworkDatagrid WPF-Virtualisierung und Befehl CanExecute

Ich habe ein Problem mit einem Datagrid auf eine WPF-Anwendung arbeiten: jede Zeile bekam 2 Befehle:

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

Und es gibt der gleiche Befehl für Movedown (kann Prüfung durchführen, wenn die Zeile nicht die letzte ist)

Und das 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> 

Wenn ich mein Raster mit EnableRowVirtualization auf true virtualisiere, habe ich einige Probleme, wenn ich nach unten scrolle (erste Zeilen nicht mehr sichtbar) und dann zurück blättern, manchmal die Schaltfläche moveup der ersten Zeile (normalerweise nicht nach oben bewegen) ist aktiviert, bis ich auf das DataGrid klicke, und auch der zweite oder der dritte ist deaktiviert, sollte aktiviert sein!

Wenn ich EnableRowVirtualization auf false gesetzt, ich habe dieses Problem nicht ...

Ich fand nur einen anderen Beitrag im Internet, die über dieses Problem zu sprechen, aber es ist nicht das Datagrid von .NET Framework : http://www.infragistics.com/community/forums/t/15189.aspx

Haben Sie eine Idee, wie kann ich es beheben?

Danke vorab in

Edit: Der Befehl Klasse

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

Ist Ihr CanExecute aufgerufen? –

+0

Geben Sie den Code der Klasse "Command" ein. –

+0

CanExecute wird beim Scrollen nicht aufgerufen – Tan

Antwort

4

Das Problem ist, wenn Sie mit dem Mausrad scrollen, wird die CanExecute nicht genannt.

Ich erstelle eine AttachedProperty, um dies zu korrigieren, und es könnte in einem Stil verwendet werden.

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

Und Sie dieses attachedProperty in einem Stil wie diese verwenden:

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

Dank Eran Otzap mir zu zeigen, warum ich dieses Problem!