我創建了自己的DataGrid它實現了一個RowClick事件。 但是在嘗試將命令綁定到它,它會拋出該異常:事件有一個不兼容的簽名 - 事件處理<T>
{「上鍵入\‘「事件\」 RowClick \ ExtendedDataGrid \’有不兼容的簽名確認該事件是公衆和滿足EventHandler委託。「}
由於我是MVVM的新手,我已經從我在過去幾天得到的關於MVVM的所有輸入中感受到了傷害。可以有人提示我(主要)明顯的錯誤?
在此先感謝
這裏是我的(testproject)代碼:
public class ExtendedDataGrid : DataGrid
{
public event EventHandler<DataGridRow> RowClick;
public ExtendedDataGrid()
{
this.DefaultStyleKey = typeof(DataGrid);
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
var row = (DataGridRow)element;
row.PreviewKeyDown += RowOnKeyDown;
row.MouseLeftButtonUp += RowOnMouseLeftButtonUp;
base.PrepareContainerForItemOverride(element, item);
}
protected override void ClearContainerForItemOverride(DependencyObject element, object item)
{
var row = (DataGridRow)element;
row.KeyUp -= RowOnKeyDown;
row.MouseLeftButtonUp -= RowOnMouseLeftButtonUp;
base.ClearContainerForItemOverride(element, item);
}
private void RowOnMouseLeftButtonUp(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
mouseButtonEventArgs.Handled = true;
this.OnRowClick((DataGridRow)sender);
}
private void RowOnKeyDown(object sender, KeyEventArgs keyEventArgs)
{
if (keyEventArgs.Key != Key.Enter)
return;
keyEventArgs.Handled = true;
this.OnRowClick((DataGridRow)sender);
}
protected virtual void OnRowClick(DataGridRow clickedRow)
{
if (null == this.RowClick)
return;
this.RowClick(this, clickedRow);
}
}
Window.xaml
<controls1:ExtendedDataGrid x:Name="extGrid">
<i:Interaction.Triggers>
<i:EventTrigger EventName="RowClick" SourceObject="{Binding ElementName=extGrid}">
<i:InvokeCommandAction Command="{Binding MyCommand}" CommandParameter="{Binding SelectedItem,ElementName=extGrid}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<controls1:ExtendedDataGrid.Items>
<TextBlock Text="Text" />
</controls1:ExtendedDataGrid.Items>
</controls1:ExtendedDataGrid>
window.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
this._selectCommand = new DelegateCommand<DataGridRow>(x =>
{
});
//following works fine..
this.extGrid.RowClick += (s, e) =>
{
};
}
private DelegateCommand<DataGridRow> _selectCommand;
public ICommand MyCommand
{
get
{
return this._selectCommand;
}
}
}
DelegateCommand實現:
public class DelegateCommand<T> : DelegateCommand
{
public DelegateCommand(Action<T> executeHandler)
: this(null, executeHandler)
{ }
public DelegateCommand(Func<T, bool> canExecuteHandler, Action<T> executeHandler)
: base(o => null == canExecuteHandler || canExecuteHandler((T)o), o => executeHandler((T)o))
{
if (null == executeHandler)
throw new ArgumentNullException("executeHandler");
}
}
/// <summary>
/// Stellt ein standard DelegateCommand dar.
/// </summary>
public class DelegateCommand : ICommand
{
#region Events
public event EventHandler CanExecuteChanged;
#endregion
#region Variablen
private readonly Action<object> _executeHandler;
private readonly Func<object, bool> _canExecuteHandler;
private bool _isExecuting = false;
#endregion
#region Eigenschaften
public bool IsSingleExecution { get; set; }
#endregion
#region Konstruktor
public DelegateCommand(Action<object> executeHandler)
: this(null, executeHandler)
{ }
public DelegateCommand(Func<object, bool> canExecuteHandler, Action<object> executeHandler)
{
if (null == executeHandler)
throw new ArgumentNullException("executeHandler");
this._executeHandler = executeHandler;
this._canExecuteHandler = canExecuteHandler;
}
#endregion
#region Public Methoden
public virtual bool CanExecute(object parameter)
{
return (!this.IsSingleExecution || (this.IsSingleExecution && !this._isExecuting)) && (null == this._canExecuteHandler || this._canExecuteHandler(parameter));
}
public virtual void Execute(object parameter)
{
if (this.CanExecute(parameter))
{
this._isExecuting = true;
this.RaiseCanExecuteChanged();
try
{
this._executeHandler(parameter);
}
finally
{
this._isExecuting = false;
this.RaiseCanExecuteChanged();
}
}
}
public void RaiseCanExecuteChanged()
{
if (null != CanExecuteChanged)
CanExecuteChanged(this, EventArgs.Empty);
}
#endregion
的事件必須是一個RoutedEvent,我打賭。 – Will