2013-11-14 81 views
5

我的工作與.NET框架的WPF應用程序4.0DataGrid的WPF虛擬化和命令CanExecute

我有一個DataGrid的一個問題:每行有兩個命令:

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

而且有

<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> 
:對於下移相同的命令

而且DataGrid中(如果該行是不是最後一個可以執行檢查)

如果我使用EnableRowVirtualization將我的網格虛擬化爲true,那麼我有一些麻煩,如果我滾動到底部(第一行不再可見),然後滾動回頂部,有時第一行的按鈕moveup(通常不能向上移動)啓用,直到我點擊DataGrid,並且第二個或第三個禁用,應該啓用!

如果我設置EnableRowVirtualization爲假,我沒有這個問題...

我只發現談論這個問題在互聯網上一個其他職位,但沒有從.NET Framework中的數據網格: 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); 
    } 
} 
+0

您的CanExecute是否被調用? –

+0

發佈'Command'類的代碼。 –

+0

CanExecute不在捲動上調用 – Tan

回答

4

問題是,當你用鼠標滾輪滾動時,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(); 
} 

而且你可以在樣式使用此attachedProperty這樣的:

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

感謝葉蘭Otzap告訴我,爲什麼我得到了這個問題!