none
Kак в WPF создать для меню командные клавиши?? RRS feed

  • Вопрос

  • Здравствуйте, из Новогодними праздниками всех!!!. Подскажите как создать класс с командами и привязать к приложению, а и именно к меню??.

        На пример: создать класс из командой, выход - Ctr+F4, или свою команду в классе и привязать ёё к меню приложение 

    4 января 2013 г. 10:18

Ответы

  • Вот, смотрите, пример из той статьи:

    public class SimpleCommand : ICommand { // Ссылка на метод который будет выполняться при активации команды (в интерфейс не входит) private Action _action; // Конструктор, т.к. класс делался для того, чтобы показать вызов разных методов,

    // то в качестве параметра и передается метод, который необходимо вызывать public SimpleCommand(Action p_action) { _action = p_action; } // Метод, возвращающий true если команда может быть выполнена, в противном случае false

    // (входит в интерфейс) // У меня, для упрощения всегда возвращается true public bool CanExecute(object parameter) { return true; } // Событие, которое необходимо вызывать, если поменялась доступность команды,

    // т.к. у меня всегда команда доступна, см. выше, то я это событие и не вызываю (входит в интерфейс) public event EventHandler CanExecuteChanged; // Метод, который вызывается, при срабатывании команды (у меня вызывается метод переданный

    // в конструктор) public void Execute(object parameter) { if (_action != null) { _action(); } } }

    Если команды вызывают трудности, то рекомендую почитать здесь.
    8 января 2013 г. 15:32
    Отвечающий
  • Простейший пример. Приложение, в котром есть синий прямоугольник. При нажатии Ctrl+R, он становится красным, при нажатии Ctrl+G - зеленым.

    Добавляем в проект два класс. SimpleCommand, я его приводил выше и вот такой:

    public class MainWindowViewModel : DependencyObject
    {
        public ICommand RedCommand { get; set; }
    
        public ICommand GreenCommand { get; set; }
    
        public SolidColorBrush RectangleColor
        {
            get { return (SolidColorBrush)GetValue(RectangleColorProperty); }
            set { SetValue(RectangleColorProperty, value); }
        }
    
        // Using a DependencyProperty as the backing store for RectangleColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RectangleColorProperty =
            DependencyProperty.Register("RectangleColor", typeof(SolidColorBrush), typeof(MainWindowViewModel), new UIPropertyMetadata(null));
    
        public MainWindowViewModel()
        {
            RectangleColor = new SolidColorBrush(Colors.Blue);
            RedCommand = new SimpleCommand(SetRed);
            GreenCommand = new SimpleCommand(SetGreen);
        }
    
        private void SetRed()
        {
            RectangleColor = new SolidColorBrush(Colors.Red);
        }
    
        private void SetGreen()
        {
            RectangleColor = new SolidColorBrush(Colors.Green);
        }
    }

    Создаем экземпляр этого класса и помещаем его в DataContext нашего главного окна:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();            
        }
    }

    Добавляем разметку:

    <Window x:Class="WpfApplication28.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.InputBindings>
            <KeyBinding Command="{Binding RedCommand}"
                    Gesture="CTRL+R" />
            <KeyBinding Command="{Binding GreenCommand}"
                    Gesture="CTRL+G" />
        </Window.InputBindings>
        <Grid>
            <Rectangle Fill="{Binding RectangleColor}" Margin="20" />
        </Grid>
    </Window>

    Запускаем, удостоверяемся, что работает:

    Чуть более подробное описание можно почитать здесь.

    P.s. Иван, если появятся вопросы, спрашивайте, постараюсь отвечать по мере возможности... Но, мне кажется, что вам не помешало бы почитать что нибудь про программирвоание на C#, про классы, свойства, методы, про WPF... Многие вопросы у вас отпадут, но появятся более интересные, над которыми и нам будет приятно голову поломать.

    9 января 2013 г. 17:12
    Отвечающий
  • Всем большое спасибо, и особенно Алексей Лосев. Вам за выдержу, хорошие пояснения темы и статьи почитав их  и этот пример, я на конец понял как оно работает!. Вот как  все реализовал. Создал класс MyCommands:


    Потом создал обработчики для команд MainWindow.xaml.cs:



    10 января 2013 г. 15:17
  • И в XAML:

    Вот и все...все работает. Жду Ваших комментариев, не судите строго)))) 
    10 января 2013 г. 15:21

Все ответы

  • Taras Kovalenko думаю вопрос связан с системой команд в WPF.

    По этому поводу советую почитать уже данную выше ссылку, а на тему своих классов команд ну хотя бы вот этот материальчик


    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    • Предложено в качестве ответа Taras KovalenkoBanned 5 января 2013 г. 20:09
    • Отменено предложение в качестве ответа Иван Лукашов 5 января 2013 г. 23:55
    5 января 2013 г. 19:42
    Отвечающий
  • Taras Kovalenko думаю вопрос связан с системой команд в WPF.

    По этому поводу советую почитать уже данную выше ссылку, а на тему своих классов команд ну хотя бы вот этот материальчик


    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    Здравствуйте, Вы меня правильно поняли...я читал вот этот материальчик , создается класс команды:

        

    public class MyCommands

    {

            // Создание командыrequery

            private static RoutedUICommand requery;

     

            static MyCommands()

            {

                // Инициализация команды

                InputGestureCollection inputs = new InputGestureCollection();

                inputs.Add(new KeyGesture(Key.R, ModifierKeys.Control, "Ctrl + R"));

                requery = new RoutedUICommand("Requery", "Requery", typeof(MyCommands), inputs);

            }

     

            public static RoutedUICommand Requery

            {

                get { return requery; }

            }

     Ну я не могу понять, как мне подключить этот класс к своему обработчику событий в  xaml:

       <RadioButton x:Name="radiobtn_off" ToolTip="Выключить звук" Click="radiobtn_off_Click">

    6 января 2013 г. 0:13

  • Вам надо в форме или контроле где вы используете кнопку сделать свойство типа ICommand 

    public ICommand Command { get; set; }

    и в разметке указать 

    <RadioButton Command="MyCommand"/>

    6 января 2013 г. 16:44
  • Вы делаете, практически все правильно, но... Ваш класс, реализующий команду должен быть потомком интерфейса ICommand. Вот, можете посмотреть пример.


    7 января 2013 г. 11:00
    Отвечающий
  • А, да, а прибиндить к свойству типа команда сочетание клавиш, можно вот так:

    <Window.InputBindings>
      <KeyBinding Command="{Binding MyCommand}"
                  Gesture="CTRL+R" />
    </Window.InputBindings>
    
    7 января 2013 г. 11:03
    Отвечающий
  • А, да, а прибиндить к свойству типа команда сочетание клавиш, можно вот так:

    <Window.InputBindings>
      <KeyBinding Command="{Binding MyCommand}"
                  Gesture="CTRL+R" />
    </Window.InputBindings>

    А как исправить вот эти ошибки??

    8 января 2013 г. 13:35
  • Кликнуть мышкой на ICommand, нажать Ctrl+. (Контрал + точка) и выбрать пункт Impliment Interface 'ICommand':

    Ну а что и как писать в появившихся методах, посмотрите в той статье, на которую я вам давал ссылку.

    8 января 2013 г. 14:58
    Отвечающий
  • Кликнуть мышкой на ICommand, нажать Ctrl+. (Контрал + точка) и выбрать пункт Impliment Interface 'ICommand':

    Ну а что и как писать в появившихся методах, посмотрите в той статье, на которую я вам давал ссылку.

    public bool CanExecute(object parameter)
            {
                throw new NotImplementedException();
            }

            public event EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                throw new NotImplementedException();
            }

    Извините, ну не могу понять, что там надо писать... можете показать код с комментариями.

    8 января 2013 г. 15:17
  • Вот, смотрите, пример из той статьи:

    public class SimpleCommand : ICommand { // Ссылка на метод который будет выполняться при активации команды (в интерфейс не входит) private Action _action; // Конструктор, т.к. класс делался для того, чтобы показать вызов разных методов,

    // то в качестве параметра и передается метод, который необходимо вызывать public SimpleCommand(Action p_action) { _action = p_action; } // Метод, возвращающий true если команда может быть выполнена, в противном случае false

    // (входит в интерфейс) // У меня, для упрощения всегда возвращается true public bool CanExecute(object parameter) { return true; } // Событие, которое необходимо вызывать, если поменялась доступность команды,

    // т.к. у меня всегда команда доступна, см. выше, то я это событие и не вызываю (входит в интерфейс) public event EventHandler CanExecuteChanged; // Метод, который вызывается, при срабатывании команды (у меня вызывается метод переданный

    // в конструктор) public void Execute(object parameter) { if (_action != null) { _action(); } } }

    Если команды вызывают трудности, то рекомендую почитать здесь.
    8 января 2013 г. 15:32
    Отвечающий
  • Если команды вызывают трудности, то рекомендую почитать здесь.
    Давал эту ссылку в самом верху, но автор вопроса похоже ленится читать.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    8 января 2013 г. 15:33
    Отвечающий
  • Если команды вызывают трудности, то рекомендую почитать здесь.

    Давал эту ссылку в самом верху, но автор вопроса похоже ленится читать.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    Я, читал ёё мне не лень просто не могу понять...вот и спрашиваю

    8 января 2013 г. 16:46
  • Спросите, что конкретно не понятно. Не в общем: "как сделать?", а "я не понимаю, как работает...".

    Мы постараемся помочь вам разобраться, но переписывать целиком уже име.щуюся статью в MSDN... Посмотрите, еще раз предлагаю, вот этот пример. Попробуйте его повторить. Если что-то не получится, спросите. Потом, попробуйте решить свой пример, по аналогии...

    8 января 2013 г. 17:09
    Отвечающий
  • Спросите, что конкретно не понятно. Не в общем: "как сделать?", а "я не понимаю, как работает...".

    Мы постараемся помочь вам разобраться, но переписывать целиком уже име.щуюся статью в MSDN... Посмотрите, еще раз предлагаю, вот этот пример. Попробуйте его повторить. Если что-то не получится, спросите. Потом, попробуйте решить свой пример, по аналогии...

    Алексей, простите ну покажите пожалуйста на моем классе:

    public class MyCommands : ICommand

    {

            // Создание командыrequery

            private static RoutedUICommand requery;

     

            static MyCommands()

            {

                // Инициализация команды

                InputGestureCollection inputs = new InputGestureCollection();

                inputs.Add(new KeyGesture(Key.R, ModifierKeys.Control, "Ctrl + R"));

                requery = new RoutedUICommand("Requery", "Requery", typeof(MyCommands), inputs);

            }

     

            public static RoutedUICommand Requery

            {

                get { return requery; }

            }

     \\ Вот тут я заглох...читал вашу статью...ну вот этот кусок так и не понял 

        public bool CanExecute(object parameter) 
            {
                throw new NotImplementedException();
            }

            public event EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                throw new NotImplementedException();
            }

         }

    }

    8 января 2013 г. 23:45
  • У вас команда доступна всегда? Если да, то CanExecute должен возвращать true, как в моем примере. И событие вызывать нет необходимости. Если же, у вас команда доступна только в ряде случаев, то в этом методе необходимо реализовать логику проверки доступности условий выполнения. Причем, если меняются условия доступности, то необходимо вызывать событие CanExecuteChanged.

    Ну а в метод Execute вы помещаете код, который будет вызываться, при срабатывании команды. В вышем случае, это код закрытия окна/приложения.

    9 января 2013 г. 3:19
    Отвечающий
  • У вас команда доступна всегда? Если да, то CanExecute должен возвращать true, как в моем примере. И событие вызывать нет необходимости. Если же, у вас команда доступна только в ряде случаев, то в этом методе необходимо реализовать логику проверки доступности условий выполнения. Причем, если меняются условия доступности, то необходимо вызывать событие CanExecuteChanged.

    Ну а в метод Execute вы помещаете код, который будет вызываться, при срабатывании команды. В вышем случае, это код закрытия окна/приложения.

    Вот как я все реализовал:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Input;

    using System.Windows.Media;
    namespace Azbuka
    {
        public class MyCommands : ICommand

    {
        MediaPlayer sound = new MediaPlayer(); //создаем экземпляр класса SoundPlayer

            // Создание командыrequery

            private static RoutedUICommand requery;



            static MyCommands()

            {

                // Инициализация команды

                InputGestureCollection inputs = new InputGestureCollection();

                inputs.Add(new KeyGesture(Key.R, ModifierKeys.Control, "Ctrl + R"));

                requery = new RoutedUICommand("Requery", "Requery", typeof(MyCommands), inputs);

            }



            public static RoutedUICommand Requery

            {

                get { return requery; }

            }


            public bool CanExecute(object parameter)
            {
                return true;
            }

            public event EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                sound.IsMuted = true;
            }
    }
    }

    P.S. Когда запускаю выдает ошибку, может я что-то не так делаю??

    9 января 2013 г. 11:46
  • Не ошибку а предупреждение, и по моему в ней ясно сказано что событие «-----» никогда не используется!

    так, я понял, что никогда не используется!...а как ёё исправить что нужно прописать?
    9 января 2013 г. 12:01
  • Ее можно не исправлять, у вас проблема в другом. Давайте вечерком, я накидаю доступный примерчик на эту тему, если вы сами не разберетесь или кто-то другой не подскажет раньше.

    9 января 2013 г. 12:03
    Отвечающий
  • Хорошо, я понимаю...что проблема в другом....потому как смотрел ваш код...если можно вечерком буду ждать доступный пример, прошу прощения за назойливости  просто...я столкнулся с этим первый раз!

    P.S. Может я что-то не так в классе делаю....мне нужна команда Ctrl + R на которою когда я нажимаю выключался звук....код который это делает у меня реализован. Я понял, что метод: 

     public void Execute(object parameter) // вызывает код, который при нажатии на Ctrl + R...будет отключать звук 
            {
                sound.IsMuted = true;
            }

    А вот метод  public event EventHandler CanExecuteChanged; // вызывается тогда когда команда выполнена...ёё можно и не указывать.

    Может, я что не так в классе написал...???

     Вы дает ошибку public event EventHandler CanExecuteChanged;// никогда не используется!
    9 января 2013 г. 12:17
  • Простейший пример. Приложение, в котром есть синий прямоугольник. При нажатии Ctrl+R, он становится красным, при нажатии Ctrl+G - зеленым.

    Добавляем в проект два класс. SimpleCommand, я его приводил выше и вот такой:

    public class MainWindowViewModel : DependencyObject
    {
        public ICommand RedCommand { get; set; }
    
        public ICommand GreenCommand { get; set; }
    
        public SolidColorBrush RectangleColor
        {
            get { return (SolidColorBrush)GetValue(RectangleColorProperty); }
            set { SetValue(RectangleColorProperty, value); }
        }
    
        // Using a DependencyProperty as the backing store for RectangleColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RectangleColorProperty =
            DependencyProperty.Register("RectangleColor", typeof(SolidColorBrush), typeof(MainWindowViewModel), new UIPropertyMetadata(null));
    
        public MainWindowViewModel()
        {
            RectangleColor = new SolidColorBrush(Colors.Blue);
            RedCommand = new SimpleCommand(SetRed);
            GreenCommand = new SimpleCommand(SetGreen);
        }
    
        private void SetRed()
        {
            RectangleColor = new SolidColorBrush(Colors.Red);
        }
    
        private void SetGreen()
        {
            RectangleColor = new SolidColorBrush(Colors.Green);
        }
    }

    Создаем экземпляр этого класса и помещаем его в DataContext нашего главного окна:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();            
        }
    }

    Добавляем разметку:

    <Window x:Class="WpfApplication28.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.InputBindings>
            <KeyBinding Command="{Binding RedCommand}"
                    Gesture="CTRL+R" />
            <KeyBinding Command="{Binding GreenCommand}"
                    Gesture="CTRL+G" />
        </Window.InputBindings>
        <Grid>
            <Rectangle Fill="{Binding RectangleColor}" Margin="20" />
        </Grid>
    </Window>

    Запускаем, удостоверяемся, что работает:

    Чуть более подробное описание можно почитать здесь.

    P.s. Иван, если появятся вопросы, спрашивайте, постараюсь отвечать по мере возможности... Но, мне кажется, что вам не помешало бы почитать что нибудь про программирвоание на C#, про классы, свойства, методы, про WPF... Многие вопросы у вас отпадут, но появятся более интересные, над которыми и нам будет приятно голову поломать.

    9 января 2013 г. 17:12
    Отвечающий
  • Простейший пример. Приложение, в котром есть синий прямоугольник. При нажатии Ctrl+R, он становится красным, при нажатии Ctrl+G - зеленым.

    Добавляем в проект два класс. SimpleCommand, я его приводил выше и вот такой:

    public class MainWindowViewModel : DependencyObject
    {
        public ICommand RedCommand { get; set; }
    
        public ICommand GreenCommand { get; set; }
    
        public SolidColorBrush RectangleColor
        {
            get { return (SolidColorBrush)GetValue(RectangleColorProperty); }
            set { SetValue(RectangleColorProperty, value); }
        }
    
        // Using a DependencyProperty as the backing store for RectangleColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RectangleColorProperty =
            DependencyProperty.Register("RectangleColor", typeof(SolidColorBrush), typeof(MainWindowViewModel), new UIPropertyMetadata(null));
    
        public MainWindowViewModel()
        {
            RectangleColor = new SolidColorBrush(Colors.Blue);
            RedCommand = new SimpleCommand(SetRed);
            GreenCommand = new SimpleCommand(SetGreen);
        }
    
        private void SetRed()
        {
            RectangleColor = new SolidColorBrush(Colors.Red);
        }
    
        private void SetGreen()
        {
            RectangleColor = new SolidColorBrush(Colors.Green);
        }
    }

    Создаем экземпляр этого класса и помещаем его в DataContext нашего главного окна:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();            
        }
    }

    Добавляем разметку:

    <Window x:Class="WpfApplication28.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.InputBindings>
            <KeyBinding Command="{Binding RedCommand}"
                    Gesture="CTRL+R" />
            <KeyBinding Command="{Binding GreenCommand}"
                    Gesture="CTRL+G" />
        </Window.InputBindings>
        <Grid>
            <Rectangle Fill="{Binding RectangleColor}" Margin="20" />
        </Grid>
    </Window>

    Запускаем, удостоверяемся, что работает:

    Чуть более подробное описание можно почитать здесь.

    P.s. Иван, если появятся вопросы, спрашивайте, постараюсь отвечать по мере возможности... Но, мне кажется, что вам не помешало бы почитать что нибудь про программирвоание на C#, про классы, свойства, методы, про WPF... Многие вопросы у вас отпадут, но появятся более интересные, над которыми и нам будет приятно голову поломать.

    А что за метот??: 
     public SolidColorBrush RectangleColor
        {
            get { return (SolidColorBrush)GetValue(RectangleColorProperty); }
            set { SetValue(RectangleColorProperty, value); }
        }
    9 января 2013 г. 18:06
  • Это не метод, это часть DependencyProperty (своства завависимости). Точнее та часть, которая свойство. Нужны для того, чтобы интерфейс узнавал о изменении состояния объекта. Вот про них более подробно.

    9 января 2013 г. 19:18
    Отвечающий
  • Всем большое спасибо, и особенно Алексей Лосев. Вам за выдержу, хорошие пояснения темы и статьи почитав их  и этот пример, я на конец понял как оно работает!. Вот как  все реализовал. Создал класс MyCommands:


    Потом создал обработчики для команд MainWindow.xaml.cs:



    10 января 2013 г. 15:17
  • И в XAML:

    Вот и все...все работает. Жду Ваших комментариев, не судите строго)))) 
    10 января 2013 г. 15:21
  • Работает? Ну и замечательно.

    Когда начнете разбираться дальше, будете делать немного по другому. Но пока, это и не важно. Главное разобрались и решили задачу.

    10 января 2013 г. 16:21
    Отвечающий
  • Это все благодаря Вам, и наверное моей дотошности и упертости))))
    10 января 2013 г. 18:31