//Add First Class
public class DataGridDoubleClickBehavior : Behavior<System.Windows.Controls.DataGrid>
{
private readonly MouseClickManager _gridClickManager;
public event EventHandler<MouseButtonEventArgs> DoubleClick;
public object CommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(DataGridDoubleClickBehavior), new PropertyMetadata(CommandParameterChanged));
private static void CommandParameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Code for dealing with your property changes
}
public ICommand DoubleClickCommand
{
get { return (ICommand)GetValue(DoubleClickCommandProperty); }
set { SetValue(DoubleClickCommandProperty, value); }
}
public static readonly DependencyProperty DoubleClickCommandProperty = DependencyProperty.Register("DoubleClickCommand", typeof(ICommand), typeof(DataGridDoubleClickBehavior), new PropertyMetadata(DoubleClickCommandChanged));
private static void DoubleClickCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Code for dealing with your property changes
}
public DataGridDoubleClickBehavior()
{
_gridClickManager = new MouseClickManager(300);
_gridClickManager.DoubleClick += new MouseButtonEventHandler(_gridClickManager_DoubleClick);
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.LoadingRow += OnLoadingRow;
AssociatedObject.UnloadingRow += OnUnloadingRow;
}
void OnUnloadingRow(object sender, DataGridRowEventArgs e)
{
//row is no longer visible so remove double click event otherwise
//row events will miss fire
e.Row.MouseLeftButtonUp -= _gridClickManager.HandleClick;
}
void OnLoadingRow(object sender, DataGridRowEventArgs e)
{
//row is visible in grid, wire up double click event
e.Row.MouseLeftButtonUp += _gridClickManager.HandleClick;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.LoadingRow -= OnLoadingRow;
AssociatedObject.UnloadingRow -= OnUnloadingRow;
}
void _gridClickManager_DoubleClick(object sender, MouseButtonEventArgs e)
{
if (DoubleClick != null)
DoubleClick(sender, e);
if (DoubleClickCommand != null)
DoubleClickCommand.Execute(CommandParameter);
}
}
//Add Second Class
public class MouseClickManager
{
#region Private members
private event MouseButtonEventHandler _click;
private event MouseButtonEventHandler _doubleClick;
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="MouseClickManager"/> class.
/// </summary>
/// <param name="control">The control.</param>
public MouseClickManager(int doubleClickTimeout)
{
this.Clicked = false;
this.DoubleClickTimeout = doubleClickTimeout;
}
#endregion
#region Events
public event MouseButtonEventHandler Click
{
add { _click += value; }
remove { _click -= value; }
}
public event MouseButtonEventHandler DoubleClick
{
add { _doubleClick += value; }
remove { _doubleClick -= value; }
}
/// <summary>
/// Called when [click].
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
private void OnClick(object sender, MouseButtonEventArgs e)
{
if (_click != null)
{
Debug.Assert(sender is Control);
(sender as Control).Dispatcher.BeginInvoke(_click, sender, e);
}
}
/// <summary>
/// Called when [double click].
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
private void OnDoubleClick(object sender, MouseButtonEventArgs e)
{
if (_doubleClick != null)
{
_doubleClick(sender, e);
}
}
/// <summary>
/// Handles the click.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
public void HandleClick(object sender, MouseButtonEventArgs e)
{
lock (this)
{
if (this.Clicked)
{
this.Clicked = false;
OnDoubleClick(sender, e);
}
else
{
this.Clicked = true;
ParameterizedThreadStart threadStart = new ParameterizedThreadStart(ResetThread);
Thread thread = new Thread(threadStart);
thread.Start(e);
}
}
}
#endregion
#region Properties
/// <summary>
/// Gets or sets a value indicating whether this <see cref="MouseClickManager"/> is clicked.
/// </summary>
/// <value><c>true</c> if clicked; otherwise, <c>false</c>.</value>
private bool Clicked { get; set; }
/// <summary>
/// Gets or sets the timeout.
/// </summary>
/// <value>The timeout.</value>
public int DoubleClickTimeout { get; set; }
#endregion
#region Methods
#region Private
/// <summary>
/// Resets the thread.
/// </summary>
/// <param name="state">The state.</param>
private void ResetThread(object state)
{
Thread.Sleep(this.DoubleClickTimeout);
lock (this)
{
if (this.Clicked)
{
this.Clicked = false;
OnClick(this, (MouseButtonEventArgs)state);
}
}
}
#endregion
#endregion
}
//and final use into xaml page
When we will use this behaviour then follow steps
1. add reference
2. add behevoiur into grid
<sdk:DataGrid Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3"
Name="DgReqForPo"
ItemsSource="{Binding Path=ReqPvList, Mode=TwoWay}"
ColumnWidth="*"
ColumnHeaderStyle="{StaticResource DGRmvdSortIconStyle}"
AutoGenerateColumns="False"
VerticalAlignment="Top"
IsReadOnly="True"
IsTabStop="False"
CanUserReorderColumns="False"
CanUserResizeColumns="False"
CanUserSortColumns="False"
GridLinesVisibility="All"
HorizontalScrollBarVisibility="Hidden"
SelectionMode="Single">
<sdk:DataGridTextColumn Binding="{Binding Path=BuyerName}" Header="Buyer"/>
<sdk:DataGridTextColumn Binding="{Binding Path=Order}" Header="OrderNo"/>
<sdk:DataGridTextColumn Binding="{Binding Path=Style}" Header="Style"/> </sdk:DataGrid.Columns>
<i:Interaction.Behaviors>
<lib:DataGridDoubleClickBehavior DoubleClickCommand="{Binding DoubleCommand}"
CommandParameter="{Binding SelectedItem,ElementName=DgReqForPo}"/>
</i:Interaction.Behaviors>
</sdk:DataGrid>
void _gridClickManager_DoubleClick(object sender, MouseButtonEventArgs e)
ReplyDelete{
if (DoubleClick != null)
DoubleClick(sender, e);
if (DoubleClickCommand != null)
DoubleClickCommand.Execute(CommandParameter);
}
// i get DoubleClickCommand = null on double click, it didn't go to view model to get value from the property bound to the DoubleClickCommand.
I got your problem. you can use static resource as a source of command binding
ReplyDelete