Simsons
Simsons

Reputation: 12745

WPF Combo box attached property for slection change not firing

To fire list box selection change I have created a attached property and binding it to my XAML like following,

<Controls:MetroWindow x:Class="Transport.MainWindow"
          xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
        xmlns:extension="clr-namespace:Transport.Extensions"
        xmlns:local="clr-namespace:Transport
        mc:Ignorable="d"
        Title="CIP Simulator" Height="550" Width="1500"
                      BorderThickness="0" 
                      GlowBrush="Black"
                      ResizeMode="CanResizeWithGrip"
                      ShowMaxRestoreButton="False"
                      WindowTransitionsEnabled="False"
                      WindowStartupLocation="CenterScreen">
 <ComboBox Grid.Column="1" Grid.Row="2" ItemsSource="{Binding Sets}" DisplayMemberPath="Set" 
                  extension:CommandProviders.Command="{Binding SetSelectionChange}"
                  SelectedItem="{Binding SelectedSet}" Grid.ColumnSpan="3"/>

Now the attached property def looks like below:

public class CommandProviders
    {
        public static ICommand GetCommand(DependencyObject depObject)
        {
            return (ICommand)depObject.GetValue(CommandProprtey);
        }

        public static void SetCommand(DependencyObject depobject, ICommand value)
        {
            depobject.SetValue(CommandProprtey, value);
        }

        public static readonly DependencyProperty CommandProprtey =
            DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(CommandProviders), null);
    }

I have now created public I command and assigned to relayCommand (which is working relay command for other buttons).

 public ICommand SetSelectionChange { get; set; }
 SetSelectionChange = new RelayCommand(commandx =>
                {
                    //Do Something

                });

But this is not firing up the selection change!!

Upvotes: 1

Views: 411

Answers (1)

user1672994
user1672994

Reputation: 10849

As mentioned in comments, you should define PropertyChangedCallback. Below is the plumbing code which subscribe for combBox Selection Changed and raise the command which should trigger the bind RelayCommand.

public class CommandProviders
{
    public static ICommand GetCommand(DependencyObject depObject)
    {
        return (ICommand)depObject.GetValue(CommandProprtey);
    }

    public static void SetCommand(DependencyObject depobject, ICommand value)
    {
        depobject.SetValue(CommandProprtey, value);
    }

    public static readonly DependencyProperty CommandProprtey =
        DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(CommandProviders), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnCommandChanged)));

}


private static void OnCommandChanged
(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ComboBox cmbBox= (ComboBox)d;
    if (cmbBox != null)     
    {
        cmbBox.SelectionChanged += (sender, eventArgs) => 
           {
               d.GetValue(CommandProprtey)?.Invoke(null);
           }
    }
}

Few other points

Wrote this code for your sample perspective. In the code, SelectionChanged event is subscribed, so you to have to see how to unsubscribe the event so that you don't end up with memory leak.

Upvotes: 2

Related Questions