Welcome to the WPF feedback portal. We’re happy you’re here! If you have feedback on how to improve the WPF, we’d love to hear it!

  • Check out the features or bugs others have reported and vote on your favorites. Feedback will be prioritized based on popularity.
  • If you have feedback that’s not listed yet, submit your own.

Thanks for joining our community and helping improve Syncfusion products!

1
Vote

I have a simple scenario:
I have a UserControl that allows editing data. On the bottom, I have action buttons (ButtonAdv) that allow doing certain actions. Each button has a command and a label that displays the assigned Shortcut.

Right now I must assign the same command to the button and to input bindings as keybinding.

This isn't a problem when I create a single UserControl, but when you have 100+ controls this becomes a mess.

When changing the shortcut I must update two places - keybinding and the label.

Ideally, each Button should have a Shortcut property that would allow us to specify a key that would trigger a command assigned to that button.

This would remove the need to modify two places and we could use SfBadge to display the Shortcut key.


EDIT:

I've managed to create a simple POC, I'm new to WPF, so I'm sure there are better ways.
The idea was that Window or UserControl should search for Buttons and register their commands as keybindings.

//add Key property to button:

    public class MyButton:ButtonAdv
    {
        public static readonly DependencyProperty KeyProperty =            DependencyProperty.Register(nameof(Key), typeof(Key), typeof(MyButton), new UIPropertyMetadata(Key.None));


        public Key Key

        {
            get => (Key)this.GetValue(KeyProperty);
            set => this.SetValue(KeyProperty, value);
        }
    }


and my base usercontrol:

    public partial class Test : UserControl
    {
        public Test()
        {
            InitializeComponent();

            var buttons = this.FindLogicalChildren();
            foreach (var button in buttons)
            {
                InputBindings.Add(new KeyBinding(button.Command, button.Key, ModifierKeys.None));
            }
        }
    }

    public sealed class TestViewModel : ViewModel
    {
        public TestViewModel(IViewModelDependencies dependencies) : base(dependencies)
        {
            ACommand = new AsyncCommand(A);
            BCommand = new AsyncCommand(B);
        }

        public AsyncCommand ACommand { get; }

        public AsyncCommand BCommand { get; }

        private async Task A()
        {
            await Task.CompletedTask;
            MessageBox.Show("A");
        }

        private async Task B()
        {
            await Task.CompletedTask;
            MessageBox.Show("B");
        }
    }

    public static class Ext
    {
        public static IEnumerable FindVisualChildren([NotNull] this DependencyObject parent) where T : DependencyObject
        {
            if (parent == null)
                throw new ArgumentNullException(nameof(parent));

            var queue = new Queue(new[] { parent });

            while (queue.Any())
            {
                var reference = queue.Dequeue();
                var count = VisualTreeHelper.GetChildrenCount(reference);

                for (var i = 0; i < count; i++)
                {
                    var child = VisualTreeHelper.GetChild(reference, I);
                    if (child is T children)
                        yield return children;

                    queue.Enqueue(child);
                }
            }
        }

        public static IEnumerable FindLogicalChildren([NotNull] this DependencyObject parent) where T : DependencyObject
        {
            if (parent == null)
                throw new ArgumentNullException(nameof(parent));

            var queue = new Queue(new[] { parent });

            while (queue.Any())
            {
                var reference = queue.Dequeue();
                var children = LogicalTreeHelper.GetChildren(reference);
                var objects = children.OfType();

                foreach (var o in objects)
                {
                    if (o is T child)
                        yield return child;

                    queue.Enqueue(o);
                }
            }
        }
    }