0

I have DataTemplate selector for my ItemsControl and I'd like to achieve something like:

        <DataTemplate x:Key="buttonTemplate">
            <Button if(someValue = true -> add thisPreviewMouseUp="button_MouseUp") PreviewMouseLeftButtonDown="button_MouseLeftButtonUp" PreviewMouseMove="button_MouseMove" Click="b_Click">
                <Button.Content>
                    <Image Source="sample.png" Height="{Binding height}" Width="{Binding width}" Stretch="Fill" HorizontalAlignment="Center" VerticalAlignment="Center" />
                </Button.Content>
                <Button.RenderTransform>
                    <RotateTransform Angle="{Binding angle}" />
                </Button.RenderTransform>
            </Button>
        </DataTemplate>

Users can move, change size of buttons from manager mode, but I don't want to fire this event in normal mode (now there is if(_fromWhere == "MANAGER") in mouse_move event)

Any idea how can I make it work?

Thanks!

user13657
  • 745
  • 3
  • 17
  • 36

2 Answers2

0

I don't know, if it's possible in XAML to set event to be fired or not.

However you can set someValue in Tag property of button and then in fired event check for Tag as proposed in this link.

    <Button Tag="{Binding someValue}" ...>

In event handler:

    bool someValue = (bool)(((Button)sender).Tag);


Edit 1:

An alternative way would be to get the DataContext of button if someValue is part of DataContext of button:

    var dataContext = ((Button)e.OriginalSource).DataContext;
    if (dataContext.someValue) 
    {
        ...
    }


Edit 2:

After a little investigation I found out that it is possible to add MouseMove event depending on someValue. Unfortunately it is unnecessarily complex I think.

     <Button Style="{Binding someValue, Converter={StaticResource BoolToButtonStyleConverter}, ConverterParameter={StaticResource MousePreviewEventSetStyle}, Mode=OneWay}" ...>

In Window.Resources define this:

    <l:BoolToButtonStyleConverter x:Key="BoolToButtonStyleConverter" />
    <Style x:Key="MousePreviewEventSetStyle" TargetType="{x:Type Button}" >
        <EventSetter Event="PreviewMouseUp" Handler="PreviewMouseUpClicked" />
    </Style>

And then in Application.Resources define this:

    <Style x:Key="clearStyle" TargetType="{x:Type Button}" />

After all you have to define:

    public class BoolToButtonStyleConverter : IValueConverter
    {
        public object Convert(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            bool someValue = (bool)value;

            if (someValue)
                return parameter;
            else
                return Application.Current.Resources["clearStyle"];
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    } 

Finally set the handler for event:

    void PreviewMouseUpClicked(object sender, RoutedEventArgs e)
    {
        ...
    }

Memo: Probably there is better way to set "default style" to button that define "clear style".

Community
  • 1
  • 1
Egres
  • 68
  • 8
0

Might help.

Mvvm Approach

I think easy way of doing this , Enable the Event only when a condition is true.

what i'm doing here i Execute a a Command Named DropUser when Event Drop Occurs. I used mvvmlight for easy commanding . you can use ICommand Wpf default commanding reference

xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mvvmlight="http://www.galasoft.ch/mvvmlight"


    <interactivity:Interaction.Triggers>
                                    <interactivity:EventTrigger EventName="Drop">
                                        <mvvmlight:EventToCommand 
                                            Command="{Binding DataContext.DropUser, 
                                            PassEventArgsToCommand="True"/>
                                    </interactivity:EventTrigger>
                                </interactivity:Interaction.Triggers>

ViewModel

 #region RelayCommand

    private RelayCommand<DragEventArgs> _dropUser;
    public RelayCommand<DragEventArgs> DropUser
    {
        get
        {
           return _dropUser ?? (_dropUser = new RelayCommand<DragEventArgs>(DropMethod,canExecute));
        }

    }

    private bool canExecute(DragEventArgs arg)
    {
        // check your condition return true . Command is only work when you return true.
    }

    #endregion

 // Method Will Fire here and do action here
 private void DropMethod(DragEventArgs eventArgs)
    {
        if (eventArgs != null)
        {
        }
    }  

what you need is like this.

<interactivity:Interaction.Triggers>
                                    <interactivity:EventTrigger EventName="PreviewMouseLeftButtonDown">
                                        <mvvmlight:EventToCommand 
                                            Command="{Binding CommandName, 
                                            PassEventArgsToCommand="True"/>
                                    </interactivity:EventTrigger>
                                </interactivity:Interaction.Triggers>

Viewmodel

 private RelayCommand<RoutedEventArgs> _commandName;

    public RelayCommand<RoutedEventArgs>CommandName
    {
        get
        {
            return commandName ?? (commandName = new RelayCommand<RoutedEventArgs>(invokeAction, canExecuteMethod));
        }


    }

    private bool canExecuteMethod()
    {
          check your condition return true
    }

    private void invokeAction(RoutedEventArgs event)
    {
        action you want to do 
    }
Community
  • 1
  • 1
Eldho
  • 7,795
  • 5
  • 40
  • 77