Hi,
what the best solution is, you have to derive from the specific task. See my demo:
----- MainWindow
<Window x:Class="WpfApp1.Window011"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
xmlns:vm="clr-namespace:WpfApp011"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d"
Title="Window011" Height="450" Width="800">
<Window.DataContext>
<vm:ViewModel/>
</Window.DataContext>
<StackPanel>
<local:Window011UC1 x:Name="MyControl" Grid.Row="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemDobleClickCommand="{Binding ItemDobleClickCommand}" />
<local:Window011UC2>
<i:Interaction.Triggers>
<i:EventTrigger EventName="ItemDobleClick">
<i:InvokeCommandAction Command="{Binding ItemDobleClickCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</local:Window011UC2>
</StackPanel>
</Window>
----- ViewModel
using System;
using System.Windows;
using System.Windows.Input;
namespace WpfApp011
{
public class ViewModel
{
private RelayCommand? _itemDobleClickCommand;
public RelayCommand ItemDobleClickCommand
{
get { return _itemDobleClickCommand ?? (_itemDobleClickCommand = new RelayCommand(param => ItemDobleClickCommandHandler(), param => true)); }
}
private void ItemDobleClickCommandHandler()
{
MessageBox.Show("ItemDobleClick");
}
}
public class RelayCommand : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _action;
public RelayCommand(Action<object> action) { _action = action; _canExecute = null; }
public RelayCommand(Action<object> action, Predicate<object> canExecute) { _action = action; _canExecute = canExecute; }
public void Execute(object o) => _action(o);
public bool CanExecute(object o) => _canExecute == null ? true : _canExecute(o);
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
}
----- UserControl with ICommand property
<UserControl x:Class="WpfApp1.Window011UC1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Label Content="DoubleClick UC1" MouseDoubleClick="RaiseItemDobleClickEvent"/>
</Grid>
</UserControl>
----- CodeBehind of UserControl
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for Window011UC1.xaml
/// </summary>
public partial class Window011UC1 : UserControl
{
public Window011UC1()
{
InitializeComponent();
}
void RaiseItemDobleClickEvent(object sender, MouseButtonEventArgs e)
{
ItemDobleClickCommand.Execute(null);
}
public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("ItemDobleClickCommand", typeof(ICommand), typeof(Window011UC1));
// Declare a get accessor method.
public static ICommand GetItemDobleClickCommand(UIElement target) => (ICommand)target.GetValue(CommandProperty);
// Declare a set accessor method.
public static void SetItemDobleClickCommand(UIElement target, ICommand value) => target.SetValue(CommandProperty, value);
public ICommand ItemDobleClickCommand
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("ItemDobleClickCommandParameter", typeof(object), typeof(Window011UC1));
public object ItemDobleClickCommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
}
}
----- UserControl with Event
<UserControl x:Class="WpfApp1.Window011UC2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Label Content="DoubleClick UC2" MouseDoubleClick="RaiseItemDobleClickEvent"/>
</Grid>
</UserControl>
----- CodeBehind of UserControl
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for Window011UC2.xaml
/// </summary>
public partial class Window011UC2 : UserControl
{
public Window011UC2()
{
InitializeComponent();
}
public static readonly RoutedEvent ItemDobleClickEvent = EventManager.RegisterRoutedEvent(
"ItemDobleClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Window011UC2));
// Provide CLR accessors for the event
public event RoutedEventHandler ItemDobleClick
{
add { AddHandler(ItemDobleClickEvent, value); }
remove { RemoveHandler(ItemDobleClickEvent, value); }
}
void RaiseItemDobleClickEvent(object sender, MouseButtonEventArgs e)
{
// Create a RoutedEventArgs instance.
RoutedEventArgs routedEventArgs = new(routedEvent: ItemDobleClickEvent);
// Raise the event, which will bubble up through the element tree.
RaiseEvent(routedEventArgs);
}
}