Hi,
all UI controls derived from FrameworkElement have the Tag property. If you don't want to use the Tag property for additional values on events, you can use your own EventArgs in your own event, like in the following demo:
XAML:
<Window x:Class="WpfApp1.Window055"
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:WpfApp055"
mc:Ignorable="d"
Title="MSCollege3000_240111" Height="450" Width="800"
local:ViewModel.AttProp="True">
</Window>
And code:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace WpfApp055
{
public class ViewModel
{
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 1. create a set of UI elements in C# (not XAML)
StackPanel stp = new StackPanel();
Wnd.Content = stp;
MyBorder b1 = new MyBorder()
{
BorderBrush = Brushes.Red,
BorderThickness = new Thickness(3),
Height = 100,
Margin = new Thickness(25),
BorderProp = "Border 1" // UniqueValue in Custom UI element
};
// 3. assign event to each UI element's MyMouseEnter event programmatically
b1.MyMouseEnter += MouseEnter;
stp.Children.Add(b1);
MyBorder b2 = new MyBorder()
{
BorderBrush = Brushes.Green,
BorderThickness = new Thickness(3),
Height = 100,
Margin = new Thickness(25),
BorderProp = "Border 2" // UniqueValue in Custom UI element
};
// 3. assign event to each UI element's MyMouseEnter event programmatically
b2.MyMouseEnter += MouseEnter;
stp.Children.Add(b2);
}
// 4. event handling
private void MouseEnter(object sender, EventArgs e)
{
// that uses the custom MouseEventArgs object with the unique value
MyEventArgs args = e as MyEventArgs;
if (args == null) return;
MessageBox.Show(args.Prop);
}
#region Attached property for attaching ViewModel with code
public static readonly DependencyProperty AttPropProperty = DependencyProperty.Register("AttProp",
typeof(bool), typeof(Window), new UIPropertyMetadata(false, OnAttProp));
public static bool GetAttProp(DependencyObject obj) => (bool)obj.GetValue(AttPropProperty);
public static void SetAttProp(DependencyObject obj, bool value) => obj.SetValue(AttPropProperty, value);
private static void OnAttProp(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
var wnd = depObj as Window;
if (wnd == null) return;
if ((e.NewValue is bool) && (bool)(e.NewValue))
{
ViewModel vm = new ViewModel();
vm.Wnd = wnd;
vm.Wnd.Loaded += vm.Window_Loaded;
}
}
Window Wnd;
#endregion
}
/// <summary>
/// Custom UI element
/// </summary>
public class MyBorder : Border
{
// UniqueValue in Custom UI element
public string BorderProp { get; set; }
// original MouseEnter event raises Custom event
protected override void OnMouseEnter(MouseEventArgs e)
{
RaiseCustomRoutedEvent(BorderProp);
base.OnMouseEnter(e);
}
// custom routed event
public static readonly RoutedEvent MyMouseEnterEvent = EventManager.RegisterRoutedEvent("MyMouseEnter",
RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyBorder));
public event RoutedEventHandler MyMouseEnter
{
add { AddHandler(MyMouseEnterEvent, value); }
remove { RemoveHandler(MyMouseEnterEvent, value); }
}
// raise custom event args class
void RaiseCustomRoutedEvent(string prop)
{
// copy UniqueValue from Custom UI element into custom event args
MyEventArgs routedEventArgs = new(MyMouseEnterEvent) { Prop = prop };
RaiseEvent(routedEventArgs);
}
}
// custom event args class
// 2. create an extension of RoutedEventArgs with an added unique property
public class MyEventArgs : RoutedEventArgs
{
public MyEventArgs(RoutedEvent routedEvent) : base(routedEvent) { }
public string Prop { get; set; }
}
}
Result: