I need to replace my button control from below to Expander control.
<Button Grid.Row="14" Grid.ColumnSpan="2" Content="{Binding InspectionLayoutAdvancedButtonContent, Mode=OneWay}" HorizontalAlignment="Stretch" Margin="10,3" MinWidth="120" Command="{Binding Path=AdvancedCommand}" Visibility="{Binding SelectedEditingLayoutViewModel.AdvancedButtonVisibility}" CommandParameter="{Binding ElementName=gridAdvances}"/> I don't know how to add Command to Expander control, so when Expander is expanded I would like to execute AdvancedCommand with parameter gridAdvanced.
How would be best way to implement this ?
Thanks.
04 Answers
Use the Expanded event:
<Expander Expanded="Expander_Expanded" /> and then call the command from the code behind:
private void Expander_Expanded(object sender, RoutedEventArgs e) { ViewModel vm = (ViewModel)DataContext; if (vm.AdvancedCommand.CanExecute(vm.gridAdvances)) vm.AdvancedCommand.Execute(vm.gridAdvances)); } Change ViewModel to whatever type your DataContext is.
Add a reference to System.Windows.Interactivity.dll (Project->Add Reference->Assemblies->Extensions in Visual Studio) and add an interaction trigger to the Expander:
<Expander xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"> <i:Interaction.Triggers> <i:EventTrigger EventName="IsExpanded" > <i:InvokeCommandAction Command="{Binding AdvancedCommand}" CommandParameter="{Binding ElementName=gridAdvances}" /> </i:EventTrigger> </i:Interaction.Triggers> </Expander> I suggest using the solution of mm8 with the event Expanded suggested by Freggar
<UserControl xmlns:i="clr-amespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"/> <Expander> <i:Interaction.Triggers> <i:EventTrigger EventName="Expanded" > <i:InvokeCommandAction Command="{Binding AdvancedCommand}" CommandParameter="{Binding ElementName=gridAdvances}" /> </i:EventTrigger> </i:Interaction.Triggers> </Expander> <UserControl> I had the same problem, for some reason it is not possible to do simple an event trigger on attached property in the TreeView object (.net core 3 + wpf).
<i:Interaction.Triggers> <i:EventTrigger EventName="Expander.Expand"> <i:InvokeCommandAction Command="{Binding MyCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> I had to solve it via custom behavior class.See below for inspiration ;)
public class TreeViewSelectionBehavior : Behavior<TreeView> { public object SelectedItem { get { return (object)GetValue(SelectedItemProperty); } set { SetValue(SelectedItemProperty, value); } } public ICommand Command { get { return (ICommand)GetValue(CommandProperty); } set { SetValue(CommandProperty, value); } } public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(TreeViewSelectionBehavior), new UIPropertyMetadata(null, OnSelectedItemChanged)); public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(TreeViewSelectionBehavior), null); private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { var item = e.NewValue as TreeViewItem; if (item != null) { item.SetValue(TreeViewItem.IsSelectedProperty, true); } } protected override void OnAttached() { base.OnAttached(); this.AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged; this.AssociatedObject.AddHandler(TreeViewItem.ExpandedEvent, new RoutedEventHandler(this.Expanded)); } private void Expanded(object sender, RoutedEventArgs e) { TreeViewItem item = e.OriginalSource as TreeViewItem; if (this.Command.CanExecute(item)) { this.Command.Execute(item); } } protected override void OnDetaching() { base.OnDetaching(); if (this.AssociatedObject != null) { this.AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged; this.AssociatedObject.RemoveHandler(TreeViewItem.ExpandedEvent, new RoutedEventHandler(this.Expanded)); } } private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) { this.SelectedItem = e.NewValue; } } Then usage is simple
<i:Interaction.Behaviors> <local:TreeViewSelectionBehavior SelectedItem="{Binding SelectedItem}" Command="{Binding ExpandHistoricalItemCommand}"/> </i:Interaction.Behaviors>