Add RoutedEvent via TemplateBinding

1.4k views Asked by At

I want to use a RoutedEvent on a Border in a XAML Dictionary. The RoutedEvent comes from the class for which the template is, how can I achieve this?

ModernWindow.cs

/// <summary>
/// Gets fired when the logo is clicked.
/// </summary>
public static readonly RoutedEvent LogoClickEvent = EventManager.RegisterRoutedEvent("LogoClickRoutedEventHandler", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ModernWindow));

/// <summary>
/// The routedeventhandler for LogoClick
/// </summary>
public event RoutedEventHandler LogoClick 
{
    add { AddHandler(LogoClickEvent, value); }
    remove { RemoveHandler(LogoClickEvent, value); }
}

/// <summary>
/// 
/// </summary>
protected virtual void OnLogoClick() 
{
    RaiseEvent(new RoutedEventArgs(LogoClickEvent, this));
}

ModernWindow.xaml

<!-- logo -->
<Border MouseLeftButtonDown="{TemplateBinding LogoClick}" Background="{DynamicResource Accent}" Width="36" Height="36" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,76,0">
    <Image Source="{TemplateBinding Logo}" Stretch="UniformToFill" />
</Border>
2

There are 2 answers

0
Knerd On BEST ANSWER

I found finally a solution, I used InputBindings and then Commands.

<Border.InputBindings>
    <MouseBinding Command="presentation:Commands.LogoClickCommand" Gesture="LeftClick" />
</Border.InputBindings>

Its not that what I wanted, but it works :)

2
Anatoliy Nikolaev On

I think in your situation, you can use EventSetter, it is just designed to do this. For you it would look something like this:

<Style TargetType="{x:Type SomeControl}">
    <EventSetter Event="Border.MouseLeftButtonDown" Handler="LogoClick" />
    ...

</Style>

Note: EvenSetter can not be set via triggers and cannot be used in a style that is contained in a theme resource dictionary, so usually it is put at the beginning of the current style.

For more information, see:

EventSetter Class in MSDN

Or if you necessary to use it in a ResourceDictionary, you can do it differently. Create the DependencyProperty (can also be attached). Example with attached DependencyProperty:

Property definition:

public static readonly DependencyProperty SampleProperty =
                                          DependencyProperty.RegisterAttached("Sample",
                                          typeof(bool),
                                          typeof(SampleClass),
                                          new UIPropertyMetadata(false, OnSample));

private static void OnSample(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    if (e.NewValue is bool && ((bool)e.NewValue) == true)
    {
        // do something...
    }
}

If you try to set the value of our property, called On Sample, in which you'll be able to do what you need (almost as well as event).

Set the value for the property, depending on the event, you might like:

<EventTrigger SourceName="MyBorder" RoutedEvent="Border.MouseLeftButtonDown">
    <BeginStoryboard>
        <Storyboard>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyBorder" Storyboard.TargetProperty="(local:SampleClass.Sample)">
                <DiscreteObjectKeyFrame KeyTime="0:0:0">
                    <DiscreteObjectKeyFrame.Value>
                        <sys:Boolean>True</sys:Boolean>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>