katit
katit

Reputation: 17915

How to change data template when item clicked?

I have ItemsControl with DataTemplate that looks like this:

enter image description here

I want to achieve effect when user clicks on item - it expands vertically and shows more info.

The only way I'm thinking is to change it to ListBox and create 2 DataTemplates for selected and regular view?

But I'd rather register click on Grid and flip property on my VM to expand this box. Is there any way to register when user clicks on Grid MVVM way?

Upvotes: 1

Views: 511

Answers (2)

Gary Barrett
Gary Barrett

Reputation: 2028

I'm not sure I'm following the question properly but is it something like the DataGrid RowDetails feature that you are seeking? It shows a detail panel for selected items:

http://wpftutorial.net/DataGrid.html#rowDetails

Upvotes: 0

Fredrik Hedblad
Fredrik Hedblad

Reputation: 84674

You can use an attached behavior for the MouseDown event.
See the following question: WPF/MVVM - how to handle double-click on TreeViewItems in the ViewModel?

In your case it would look like this

<ItemsControl ItemsSource="{Binding ...}">
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="commandBehaviors:MouseDown.Command"
                    Value="{Binding YourItemClickCommand}"/>
            <Setter Property="commandBehaviors:MouseDown.CommandParameter"
                    Value="{Binding}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <!-- ... -->
</ItemsControl>

MouseDown

public class MouseDown
{
    public static DependencyProperty CommandProperty =
        DependencyProperty.RegisterAttached("Command",
                                            typeof(ICommand),
                                            typeof(MouseDown),
                                            new UIPropertyMetadata(CommandChanged));

    public static DependencyProperty CommandParameterProperty =
        DependencyProperty.RegisterAttached("CommandParameter",
                                            typeof(object),
                                            typeof(MouseDown),
                                            new UIPropertyMetadata(null));

    public static void SetCommand(DependencyObject target, ICommand value)
    {
        target.SetValue(CommandProperty, value);
    }

    public static void SetCommandParameter(DependencyObject target, object value)
    {
        target.SetValue(CommandParameterProperty, value);
    }
    public static object GetCommandParameter(DependencyObject target)
    {
        return target.GetValue(CommandParameterProperty);
    }

    private static void CommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        Control control = target as Control;
        if (control != null)
        {
            if ((e.NewValue != null) && (e.OldValue == null))
            {
                control.MouseDown += OnMouseDown;
            }
            else if ((e.NewValue == null) && (e.OldValue != null))
            {
                control.MouseDown -= OnMouseDown;
            }
        }
    }

    private static void OnMouseDown(object sender, RoutedEventArgs e)
    {
        Control control = sender as Control;
        ICommand command = (ICommand)control.GetValue(CommandProperty);
        object commandParameter = control.GetValue(CommandParameterProperty);
        command.Execute(commandParameter);
    }
}

Upvotes: 1

Related Questions