Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
21 / 17 / 1
Регистрация: 01.09.2019
Сообщений: 262

ICommand и radiobutton взаимоотношения

04.03.2020, 11:36. Показов 3915. Ответов 39
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет,

если с просто button_click все ясно,
то как быть с radio button в случае использования ICommand?

XML
1
2
3
4
5
6
7
8
9
10
<RadioButton
                    x:Name="Radiobutton_1099"
                    Grid.Column="0"
                    Width="56"
                    Height="22"
                    Margin="2"
                    HorizontalAlignment="Left"
                    Checked="?????????????"
                    Content="Busy"
                    Unchecked="???????????" />
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.03.2020, 11:36
Ответы с готовыми решениями:

ICommand в WPF
Доброго времени суток. Только начинаю осваивать WPF, прощу помощи. Как реализовать сохранение контактов, добавленных в приложении, в файл?

Комманды и ICommand
Привет всем. Вот сижу разбираюсь с MVVM и никак не могу понять суть работы команды. Зачем необходимо ее наследовать от ICommand и для чего...

UWP ICommand реализация
Добрый день. Кому не жалко поделитесь реализацией ICommand для UWP. А то эта реализация не подходит (взята с cyberforum)....

39
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
04.03.2020, 18:18
Студворк — интернет-сервис помощи студентам
Ахромчон, вот вам развёрнутый пример использования RadioButton для выбора одного из значений перечисления.
Это пример демонстрирует присущие RadioButton особенности:
Это групповой элемент и выбран может только один из них
Они предназначены для Представления данных с жёстко заданными вариантами значений
Само по себе состояние каждого RadioButton значение не имеет.

Перечисление
C#
1
2
3
4
5
6
7
    public enum NumbersEnum
    {
        Ноль,
        Один,
        Два,
        Три
    }
ViewModel
C#
1
2
3
4
5
6
7
8
9
    public class ViewModel : OnPropertyChangedClass
    {
        private NumbersEnum _number;
        public NumbersEnum Number { get => _number; set => SetProperty(ref _number, value); }
 
        private RelayCommand _numberCommand;
        public RelayCommand NumberCommand => _numberCommand
            ?? (_numberCommand = new RelayCommand(p => Number = (NumbersEnum)p));
    }
Для Представления используется типовой мультиконвертер для сравнения значений
C#
1
2
3
4
5
6
7
8
9
10
    public class EqualsConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
            => values?.Length == 2 && values[0].Equals(values[1]);
 
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
Представление.
В нём используется общий стиль для всех одинаковых RadioButton.
Но для каждого задан свой Контент соответсвующий его значению
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <local:EqualsConverter x:Key="EqualsConverter"/>
        <Style TargetType="RadioButton">
            <Setter Property="IsChecked">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource EqualsConverter}" Mode="OneWay">
                        <Binding Path="Number"/>
                        <Binding Path="Content" RelativeSource="{RelativeSource Self}"/>
                    </MultiBinding>
                </Setter.Value>
            </Setter>
            <Setter Property="Command" Value="{Binding NumberCommand}"/>
            <Setter Property="CommandParameter" Value="{Binding Content, RelativeSource={RelativeSource Self}}"/>
        </Style>
    </Window.Resources>
    <StackPanel>
        <TextBlock Text="{Binding Number}"/>
        <RadioButton Content="{x:Static local:NumbersEnum.Ноль}"/>
        <RadioButton Content="{x:Static local:NumbersEnum.Один}"/>
        <RadioButton Content="{x:Static local:NumbersEnum.Два}"/>
        <RadioButton Content="{x:Static local:NumbersEnum.Три}"/>
    </StackPanel>
1
21 / 17 / 1
Регистрация: 01.09.2019
Сообщений: 262
04.03.2020, 21:32  [ТС]
test
0
21 / 17 / 1
Регистрация: 01.09.2019
Сообщений: 262
05.03.2020, 07:59  [ТС]
Элд Хасп,

посмотрел в сети -это реальная проблема для тех кто пользуется MVVM. Все пишут костыли.
Почему проблема? Потому что чтобы использовать два несчастных события любезно предоставленных в CB,
в случае с использованием MVVM это превращается в пару десятков строк. Ну не умеет MVVM то что умеет CB!
В MVVM такая изящная и полезная Command (в случае с Button_click), совершенна бесполезна в случае Checked, Unchecked.
вот нельзя ее разорвать на две. Нет, можно конечно = "костылем".

Хотел спросить, наряду с пользованием с основной массой компонентов

XML
1
2
3
 <Window.DataContext>
        <vm:MainViewModel />
    </Window.DataContext>

хотел бы пользоваться из CB для радиокнопок, в свете того, что MVVM без костылей не может рабоать с Radiobuttons.

C#
1
 ((ViewModel)DataContext).DoSomethingMethod();
0
управление сложностью
 Аватар для Почтальон
1693 / 1306 / 259
Регистрация: 22.03.2015
Сообщений: 7,545
Записей в блоге: 5
05.03.2020, 09:27
Ахромчон, я понимаю ваше негодование, сейчас начал возиться с TreeView и это полный треш....
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
05.03.2020, 10:07
Цитата Сообщение от Ахромчон Посмотреть сообщение
посмотрел в сети -это реальная проблема для тех кто пользуется MVVM.
Проблема возникает только в случае отсутствия нормального разделения Данных и их Представления.
И несмотря на реализацию MVVM (а это ярко выраженный паттерн ООП) мышление, привычки остались от процедурного программирования.

Я вам дал несколько примеров. Вам по всей видимости они не подходят.
Покажите как у вас привязаны RadioButton к данным и что вы хотите сделать по тому или иному изменению RadioButton.

Добавлено через 18 минут
Ахромчон, Я почему за это пишу.
Привязка RaddioButton к данным далеко не такая тривиальная как TextBlock.
RaddioButton это ГРУППОВОЙ элемент.
Очень редко в данных бывают свойства которые напрямую можно привязать к группе RaddioButton.
Выше я показал пример возможной привязки.
Там для привязки к ОДНОМУ свойству надо использовать ГРУППУ RaddioButton и делать это приходится через конвертер.
0
21 / 17 / 1
Регистрация: 01.09.2019
Сообщений: 262
05.03.2020, 10:50  [ТС]
Элд Хасп, я бы использовал "костыли". Даже нашел один в сети. Но у меня есть такое необычное свойство.
Я после 3-х... 6-ти месяцев гляжу на собственный код уже рабочего и сданного приложения, и не верю глазам своим, что я это написал. И могу целый день "бычить" на это ничего не понимая как это работает. Чем меньше прямой логики в коде, тем больше приходится "бычить". А время -деньги! Наверное потому, что я не занимаюсь этим 24/7 в неделю.

Элд Хасп, логика простейшая, в которой невозможно ошибиться.

В ХAML две радиокнопки. У каждой создано по два события Checked, Unchecked соотвественно.

В Сode Behind

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void RadioButton1_Checked(object sender, RoutedEventArgs e)
        {
                 // садим бит 1  в "true"
        }
 
 private void RadioButton1_Unchecked(object sender, RoutedEventArgs e)
        {
                // садим бит 1  в "false"
        }
 
 
 private void RadioButton2_Checked(object sender, RoutedEventArgs e)
        {
                 // садим бит 2  в "true"
        }
 
 
 private void RadioButton2_Unchecked(object sender, RoutedEventArgs e)
        {
                // садим бит 2  в "false"
        }
Все!

Добавлено через 9 минут
сейчас вышел из положения так

в события вписал вот это и устанавливаю биты в VM. Например.

C#
1
(ViewModel)DataContext).SetBit1();
0
800 / 583 / 207
Регистрация: 21.02.2019
Сообщений: 2,095
05.03.2020, 11:11
.. я всё-таки не пойму, зачем четыре метода, где должен быть один ..?
0
управление сложностью
 Аватар для Почтальон
1693 / 1306 / 259
Регистрация: 22.03.2015
Сообщений: 7,545
Записей в блоге: 5
05.03.2020, 11:12
Ахромчон, нужно в сеттерах это все делать....
0
180 / 95 / 25
Регистрация: 04.02.2016
Сообщений: 308
Записей в блоге: 3
05.03.2020, 11:17
Если правильно понял автора, то вот. Если неправильно, то и ладно
XML
1
2
3
4
5
6
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
        <RadioButton Content="Radio1" IsChecked="{Binding IsCheckRadio1}" Margin="10"
                     Command="{Binding Radio1Check}"/>
        <RadioButton Content="Radio2" IsChecked="{Binding IsCheckRadio2}" Margin="10"
                     Command="{Binding Radio2Check}"/>
</StackPanel>
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class ViewModel : OnPropertyChangedClass
    {
        private bool _isCheckRadio1;
        private bool _isCheckRadio2;
 
        public bool IsCheckRadio1
        {
            get { return _isCheckRadio1; }
            set
            {
                _isCheckRadio1= value;
                OnPropertyChanged();
            }
        }
        public bool IsCheckRadio2
        {
            get { return _isCheckRadio2; }
            set
            {
                _isCheckRadio2= value;
                OnPropertyChanged();
            }
        }
        public ViewModel()
        {
            IsCheckRadio2 = true;
            IsCheckRadio1 = false;
        }
        public ICommand Radio1Check => new Command(obj => RadioCheck());
        public ICommand Radio2Check => new Command(obj => RadioCheck());
        private void RadioCheck()
        {
            if(IsCheckRadio1 == true)
            {
                //что-то делаем
            } else if(IsCheckRadio2 == true)
            {
                //что-то делаем
            }
        }
    }
1
21 / 17 / 1
Регистрация: 01.09.2019
Сообщений: 262
05.03.2020, 11:33  [ТС]
Hugonavy,

C#
1
2
3
4
5
6
7
8
9
10
 private void RadioCheck()
        {
            if(IsCheckRadio1 == true)
            {
                //что-то делаем
            } else if(IsCheckRadio2 == true)
            {
                //что-то делаем
            }
        }

Этого "добра" в сети полно, как будто один у другого списывает.


В первом "что-то делаем", хорошо, садим бит.
Когда кнопка становится Unchecked где его снимаем?

В соседней кнопке? Мне даже такой "горотьбы" не надо, чтобы исполнить у соседа.

А вот снять бит той же кнопкой, что был посажен. Большой вопрос. Только в СB.
0
управление сложностью
 Аватар для Почтальон
1693 / 1306 / 259
Регистрация: 22.03.2015
Сообщений: 7,545
Записей в блоге: 5
05.03.2020, 11:54
Ахромчон, смысл ваших вопросов, если и так все делаете по-своему ?

Добавлено через 2 минуты
Цитата Сообщение от Ахромчон Посмотреть сообщение
А вот снять бит той же кнопкой, что был посажен. Большой вопрос. Только в СB.
Для этого создается приватная переменная, состояние которой проверяется и устанавливается в сеттерах забиндинных свойств

Добавлено через 1 минуту
Я понимаю что вы электронщик, и мыслите линейно (так привыкли) и пытаетесь ООП подвести под функциональщину, поэтому и негодуете, т.к. это идет вразрез с вашей логикой.
0
800 / 583 / 207
Регистрация: 21.02.2019
Сообщений: 2,095
05.03.2020, 11:57
.. я не знаю WPF, но подозреваю, что в метод CodeBehind можно передать sender-а? ... вот его через switch и переменную в true, остальных в false ... ну это же взаимозависимые элементы одного контрола, а не независимые ... в радиоприемниках дедушкиных так диапазоны переключались ...
0
-21 / 29 / 2
Регистрация: 17.03.2018
Сообщений: 778
05.03.2020, 12:32
Самый большой промах знатоков ООП, что они считают, что ООП сделано само для себя. Да, есть такие приложения типа Калькулятора зацикленные сами на себя.
Но в реальной жизни кому они нужны? В Винде есть, на столе тоже лежит.
0
21 / 17 / 1
Регистрация: 01.09.2019
Сообщений: 262
05.03.2020, 12:41  [ТС]
Цитата Сообщение от carrotik Посмотреть сообщение
. я не знаю WPF, но подозреваю, что в метод CodeBehind можно передать sender-а? ... вот его через switch и переменную в true, остальных в false ... ну это же взаимозависимые элементы одного контрола, а не независимые ... в радиоприемниках дедушкиных так диапазоны переключались ...
Если сравнивать с Элд Хасп, я тоже не знаю WPF и С#, если сравнивать с соседом, то знаю и даже что-то лабаю.
1
управление сложностью
 Аватар для Почтальон
1693 / 1306 / 259
Регистрация: 22.03.2015
Сообщений: 7,545
Записей в блоге: 5
05.03.2020, 12:47
Цитата Сообщение от Ахромчон Посмотреть сообщение
если сравнивать с соседом, то знаю и даже что-то лабаю.
Ну вы еще с ребенком себя сравните, +100500 к карме
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
05.03.2020, 16:28
Цитата Сообщение от Ахромчон Посмотреть сообщение
логика простейшая, в которой невозможно ошибиться.
В ХAML две радиокнопки. У каждой создано по два события Checked, Unchecked соотвественно.
В Сode Behind
Даже из этой фразу понятно что у вас не выйдет ПРАВИЛЬНО MVVM!

Основная часть WPF Решения сделанного в паттерне MVVM - это Модель.
А WPF это всего лишь Представление данных полученных из Model.

Вот вы пишите // садим бит 1 в "true".
Какой в Представлении может быть бит ??? !!! Бит сам по себе?
Где данные и как это бит с ними связан?

Для создания Представления нужно сначала создать привязку этого представления к данным.
А что у вас Представляют RadioButton - сами себя? Ну, тогда это никакой не MVVM.

Допустим, в моём примере я явно не выделил Модель. Так как думал, что из-за простоты примера это и так понятно.
В том примере, перечисление NumbersEnum, свойство Number и метод создаваемый лямбдой p => Number = (NumbersEnum)p - это часть Model. К ViewModel относится только сама команда, которая обращается к методу Модели, и свойство Number, которое не будет иметь своего сеттера, а только привязку к свойству Модели.

Поэтому, создайте сначала Модель. В том числе все методы для работы с данными. И тогда 90% вопросов по View у вас сами собой отпадут.

Начиная создавать приложение с другого конца (с WPF View) вы сами себе создаёте кучу трудностей, которые героически преодолеваете, но которые, по сути, совершенно не нужны для нормальной работы приложения.
Цитата Сообщение от Hugonavy Посмотреть сообщение
Если правильно понял автора, то вот. Если неправильно, то и ладно
Не правильно.
Ошибка та же, что и Ахромчон.

Что представляют RadioButton?
У вас - по сути, сами себя.
А у ТС - по идее, биты чего-то.
Вот этой привязки к данным нет ни у вас, ни у самого Ахромчон

Добавлено через 9 минут
Цитата Сообщение от Bulky Посмотреть сообщение
Самый большой промах знатоков ООП, что они считают, что ООП сделано само для себя. Да, есть такие приложения типа Калькулятора зацикленные сами на себя.
Но в реальной жизни кому они нужны? В Винде есть, на столе тоже лежит.
Самый большой пропах незнающих ООП думать, что знающие его не знают, что такое процедурное программирование без ООП. Процедурное программирования в любом случае используется как часть ООП, от него ни куда не денешься.

Хорошие знание и практика ООП кроме всего прочего ещё наводит и "порядок в голове". Что позволяет делать гораздо белее "красивый" процедурный код.

Добавлено через 10 минут
Цитата Сообщение от Ахромчон Посмотреть сообщение
Если сравнивать с Элд Хасп, я тоже не знаю WPF и С#
У меня выйти на более менее приемлемый уровень получилось за несколько месяцев, от силы за полгода.
До этого о C# только слышал, о WPF - даже названия не знал.

Но при осваивании я сам себе запретил делать "костыли".
Ни чего. По началу было трудно, но больше из-за бардака в голове в котором приходилось наводить порядок.

Вы так же не делайте костылей и по неволе освоите.
По этой причине, я уже многократно писал.
Начинающим, для быстрейшего освоение правильной реализации WPF решений, при создании окон надо оставлять их CB совершено пустым.
1
-21 / 29 / 2
Регистрация: 17.03.2018
Сообщений: 778
05.03.2020, 16:49
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Начинающим, для быстрейшего освоение правильной реализации WPF решений, при создании окон надо оставлять их CB совершено пустым.
Золотые слова! Оставил CB почти пустым и тут же поймал глюк. novikov.ea, ворчит , что кода недостаточно, а я думаю, я искать сам буду дольше или код вываливать на форум буду дольше. Дилеммка.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
05.03.2020, 20:15
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Допустим, в моём примере я явно не выделил Модель.
Вот ещё более развёрнутый пример.
С выделенной Моделью, чтобы было понятно, что RadioButton - это не "вещь в себе", а Представление Данных, находящихся в Model.
C#
1
2
3
4
5
6
7
8
9
    /// <summary>Это тип данных для МОДЕЛИ.
    /// Аналогично DTO типам и т.п.</summary>
    public enum NumbersEnum
    {
        Ноль,
        Один,
        Два,
        Три
    }
C#
1
2
3
4
5
6
7
8
9
10
    /// <summary>Модель понятия не имеет ни о каких RadioButton и командах
    /// Ей это для работы не нужно.</summary>
    public class Model : OnPropertyChangedClass
    {
        private NumbersEnum _number;
        public NumbersEnum Number { get => _number; private set => SetProperty(ref _number, value); }
 
        public void SetNumber(NumbersEnum number)
            => Number = number;
    }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
   /// <summary>ViewModel это всего лишь согласующий слой между Моделью и View.
   /// Ни каких данных в ней меняться не должно и она знать не знает как
   /// View будет Представлять свойство Number и вызывать команду NumberCommand
   /// Как именно будет меняться свойство в Модели и будет ли оно, вообще, меняться
   /// ViewModel тоже не знает</summary>
    public class ViewModel : OnPropertyChangedClass
    {
        private readonly Model model = new Model();
 
        public NumbersEnum Number => model.Number;
 
        private RelayCommand _numberCommand;
        public RelayCommand NumberCommand => _numberCommand
            ?? (_numberCommand = new RelayCommand(p => model.SetNumber((NumbersEnum)p)));
 
        public ViewModel()
        {
            /// Сквозная "прокидка" PropertyChanged через ViewModel
            /// Используется когда в VM и Model одноимённый свойства
            model.PropertyChanged += (s, e)
                => OnPropertyChanged(e.PropertyName);
        }
    }
XAML тот же
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <local:EqualsConverter x:Key="EqualsConverter"/>
        <Style TargetType="RadioButton">
            <Setter Property="IsChecked">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource EqualsConverter}" Mode="OneWay">
                        <Binding Path="Number"/>
                        <Binding Path="Content" RelativeSource="{RelativeSource Self}"/>
                    </MultiBinding>
                </Setter.Value>
            </Setter>
            <Setter Property="Command" Value="{Binding NumberCommand}"/>
            <Setter Property="CommandParameter" Value="{Binding Content, RelativeSource={RelativeSource Self}}"/>
        </Style>
    </Window.Resources>
    <StackPanel>
        <TextBlock Text="{Binding Number}"/>
        <RadioButton Content="{x:Static local:NumbersEnum.Ноль}"/>
        <RadioButton Content="{x:Static local:NumbersEnum.Один}"/>
        <RadioButton Content="{x:Static local:NumbersEnum.Два}"/>
        <RadioButton Content="{x:Static local:NumbersEnum.Три}"/>
    </StackPanel>
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
05.03.2020, 20:59
Ахромчон, Bulky, Hugonavy, carrotik, одной из ключевых возможностей MVVM является возможность изменения View не влияющая на VM.
Если использовать обработку событий Checked и Unchecked, то мы жёстко завязываем ViewModel на конкретную реализацию View. Так как такие события есть только у RadioButton.

В примере же из моего поста выше мы без проблем можем изменить View заменив его на ComboBox.

Используем слегка дополненный WPF конвертер из темы WPF конвертеры [Элд Хасп]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    /// <summary>WPF конвертер для получения списка значений перечисления</summary>
    public class EnumsIEnumerableConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Type type;
            if (
                    (value != null && (type = value.GetType()).IsEnum)
                    || (parameter is string parStr && (type = Type.GetType(parStr)) != null && type.IsEnum)
                    || ((type =parameter as Type) != null && type.IsEnum)
                )
                return Enum.GetValues(type);
            throw new ArgumentException();
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
И вот простой XAML. Из особенностей только использование C# - можно тоже самое сделать привязкой команды к событию, но не хотел подключать Interactivity или использовать Code Behind
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <local:EnumsIEnumerableConverter x:Key="EnumsIEnumerableConverter"/>
        <Style TargetType="RadioButton">
            <Setter Property="IsChecked">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource EqualsConverter}" Mode="OneWay">
                        <Binding Path="Number"/>
                        <Binding Path="Content" RelativeSource="{RelativeSource Self}"/>
                    </MultiBinding>
                </Setter.Value>
            </Setter>
            <Setter Property="Command" Value="{Binding NumberCommand}"/>
            <Setter Property="CommandParameter" Value="{Binding Content, RelativeSource={RelativeSource Self}}"/>
        </Style>
    </Window.Resources>
    <StackPanel>
        <TextBlock Text="{Binding Number}"/>
        <ComboBox ItemsSource="{Binding Converter={StaticResource EnumsIEnumerableConverter}, ConverterParameter={x:Type local:NumbersEnum}}"
                  SelectedItem="{Binding Number, Mode=OneWay}" SelectionChanged="ComboBox_SelectionChanged">
        </ComboBox>
        <x:Code>
            <![CDATA[void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
               Selector cntrl =  (Selector)sender;
               ((ViewModel)cntrl.DataContext).NumberCommand.Execute(cntrl.SelectedItem);
            }
            ]]>
        </x:Code>
    </StackPanel>
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
05.03.2020, 20:59
Ахромчон, Bulky, Hugonavy, carrotik, одной из ключевых возможностей MVVM является возможность изменения View не влияющая на VM.
Если использовать обработку событий Checked и Unchecked, то мы жёстко завязываем ViewModel на конкретную реализацию View. Так как такие события есть только у RadioButton.

В примере же из моего поста выше мы без проблем можем изменить View заменив его на ComboBox.

Используем слегка дополненный WPF конвертер из темы WPF конвертеры [Элд Хасп]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    /// <summary>WPF конвертер для получения списка значений перечисления</summary>
    public class EnumsIEnumerableConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Type type;
            if (
                    (value != null && (type = value.GetType()).IsEnum)
                    || (parameter is string parStr && (type = Type.GetType(parStr)) != null && type.IsEnum)
                    || ((type =parameter as Type) != null && type.IsEnum)
                )
                return Enum.GetValues(type);
            throw new ArgumentException();
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
И вот простой XAML. Из особенностей только использование C# - можно тоже самое сделать привязкой команды к событию, но не хотел подключать Interactivity или использовать Code Behind
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <local:EnumsIEnumerableConverter x:Key="EnumsIEnumerableConverter"/>
        <Style TargetType="RadioButton">
            <Setter Property="IsChecked">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource EqualsConverter}" Mode="OneWay">
                        <Binding Path="Number"/>
                        <Binding Path="Content" RelativeSource="{RelativeSource Self}"/>
                    </MultiBinding>
                </Setter.Value>
            </Setter>
            <Setter Property="Command" Value="{Binding NumberCommand}"/>
            <Setter Property="CommandParameter" Value="{Binding Content, RelativeSource={RelativeSource Self}}"/>
        </Style>
    </Window.Resources>
    <StackPanel>
        <TextBlock Text="{Binding Number}"/>
        <ComboBox ItemsSource="{Binding Converter={StaticResource EnumsIEnumerableConverter}, ConverterParameter={x:Type local:NumbersEnum}}"
                  SelectedItem="{Binding Number, Mode=OneWay}" SelectionChanged="ComboBox_SelectionChanged">
        </ComboBox>
        <x:Code>
            <![CDATA[void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
               Selector cntrl =  (Selector)sender;
               ((ViewModel)cntrl.DataContext).NumberCommand.Execute(cntrl.SelectedItem);
            }
            ]]>
        </x:Code>
    </StackPanel>
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.03.2020, 20:59

ICommand и Template, Command Parametr
Доброго времени суток. У меня имеется код наподобие этого: &lt;ListBox ItemsSource=&quot;{Binding}&quot; ...

[WPF] Передать параметр в ICommand
Добрый день. Делаю проект wpf - mvvm. Из главного окна требуется вызвать дочернее окно и передать туда индекс или элемент из листбокса...

Свойство не обновляется через ICommand
Сделал простенький пример. CommandHandler public class CommandHandler : ICommand { private Action&lt;object&gt;...

Полное представление async ICommand
Есть ли у кого примеры или может вообще готовое решение? А именно: класс с асинхронным запуском команд, вместо RelayCommand (как обычно его...

EventArgs при использовании ICommand для событий в MVVM
Пытаюсь, вроде как, делать программу по законам MVVM. И всё пока отлично, за исключением событий интерфейса, например, Drag'n'drop, или...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru