Dynamically set event handler using DataTrigger
Asked Answered
G

2

10

iv'e got several itemscontrols which i need to attach an event handler for their PreviewMouseLeftButtonDown event only when a certain condition is met .

iv'e designed a style for my controls with a datatrigger ,i checked out it's bindings and tried it out with a regular property setter for the BorderThickness Property just to see that the datatrigger works . (It does..)

how can i apply my datatrigger to attach an event handler when the condition of the datatrigger is met using an event setter in the same manner i would a regular property setter ?

something along the lines of :

     <Style TargetType="{x:Type ItemsControl}">                              
        <Style.Triggers>
            <DataTrigger Binding="{Binding Turn}" Value="True">
                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ItemsControl_MouseLeftButtonDown"></EventSetter>
            </DataTrigger>                            
        </Style.Triggers>
     </Style>

this markup throws the following exception on the eventsetter line :

    'Set property 'System.Windows.EventSetter.Event' threw an exception.' 

Inner Exception :

       {"Value cannot be null.\r\nParameter name: value"}
Grantley answered 12/3, 2012 at 20:1 Comment(2)
exactly which line throws that exception? Is it `<DataTrigger Binding="{Binding Turn}" Value="True">' ?Slapstick
@XiaoChuanYu <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ItemsControl_MouseLeftButtonDown"></EventSetter>Grantley
S
18

Unfortunately according to MSDN doc under Remarks:

Note that only Style.Setters supports EventSetter objects. Triggers (TriggerBase and derived classes) do not support EventSetter

In this case, DataTrigger is derived from TriggerBase so you can't use it to set event handlers dynamically. A workaround I can think of right now might be to dynamically switch styles based on value of Turn.

Slapstick answered 12/3, 2012 at 22:31 Comment(5)
i actually thought of registering a dependency property , which would something like my:mouseleftbuttondown="True" , and use it in a setter i don't know if i could use custom dependency property's in a setter ..Grantley
I kinda doubt it fits your situation but you may want to look at #1138839Slapstick
that's a good idea , ill design a style based on the style i already have and do something like . <ItemsControl Style="{Binding Turn,Converter={StaticResources MyTurnToStyleConverter}" />Grantley
hmm, how are you going to get a reference to the styles?Slapstick
don't really know yet .... i don't have time to deal with it now , maybe i could give the Handler value of the eventsetter a binding value and set it ether to null or a reference to a handler , again i don't know if that's possible ether , i'll post a solution when i figure it out.Grantley
D
0

You can use a StyleSelector

public sealed class NewItemPlaceholderStyleSelector : StyleSelector
{
    public Style? Style { get; set; }

    public override Style? SelectStyle(object? item, DependencyObject container)
    {
        if (NewItemPlaceholder.IsMatch(item))
        {
            return this.Style;
        }

        return base.SelectStyle(item, container);
    }
}
<DataGrid ...>
    <DataGrid.ItemContainerStyleSelector>
        <local:NewItemPlaceholderStyleSelector>
            <local:NewItemPlaceholderStyleSelector.Style>
                <Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}">
                    <EventSetter Event="MouseDoubleClick" Handler="OnMouseDoubleClick" />
                </Style>
            </local:NewItemPlaceholderStyleSelector.Style>
        </local:NewItemPlaceholderStyleSelector>
    </DataGrid.ItemContainerStyleSelector>
Delivery answered 28/10, 2022 at 15:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.