Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
1 / 1 / 0
Регистрация: 15.08.2016
Сообщений: 58
WPF

Сохранить значения выбранных чекбоксов в листбокс

28.02.2020, 08:09. Показов 1711. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
На WPF только начинаю переходить. Просьба не ругать.
В WinForm все было понятно. Есть N чекбоксов и чекбокс
ВЫБРАТЬ ВСЕ. имя чекбоксов cbVP1, cbVP2 ... cbVP32
cboxOnOffAll имя чекбокса ВЫБРАТЬ ВСЕ реализация на
WinForm следующая
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
        private void cboxOnOffVP_CheckedChanged(object sender, EventArgs e)
        {//событие ВЫБРАТЬ ВСЕ
             CheckBox cboxOnOffVP = (CheckBox)sender;
             if (cboxOnOffVP.Checked)
                 {
                      cboxOnOffVP.Text = "Выбраны все";
                      for (int i = 0; i < 32; i++)
                      {
                          ((CheckBox)Controls["cbVP" + (i + 1).ToString()]).Checked = true;
                          //изменение состояния всех чекбоксов cbVP1, cbVP2 ... cbVP32 в цикле
                      }
                 }
         }
Реализация получения значений выбранных чекбоксов
(значения записываются в листбокс)
на WinForm через таймер

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void timerVP_Tick(object sender, EventArgs e)
        {
            if (listVP.Items.Count < 32) cboxOnOffVP.Text = "Выбрать все";
            if (listVP.Items.Count == 32 && cboxOnOffVP.Checked == true) cboxOnOffVP.Text = "Выбраны все";
            timerlabel.Enabled = false;
            listVP.Items.Clear();
            for (int i = 0; i < 32; i++)
            {
                if (((CheckBox)Controls["cbVP" + (i + 1).ToString()]).Checked)
                {
                    listVP.Items.Add(((CheckBox)Controls["cbVP" + (i + 1).ToString()]).Text);
                    // запись значений в листбокс выбранных чекбоксов
                }
            }
         }
Пытаюсь сделать реализацию на WPF следующим образом
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
26
27
28
29
30
31
32
33
<Style TargetType="{x:Type ListBox}" x:Key="CheckBoxListStyle" >
            <Setter Property="SelectionMode" Value="Multiple" />
            <Setter Property="ItemContainerStyle">
                <Setter.Value>
                    <Style TargetType="{x:Type ListBoxItem}">
                        <Setter Property="Margin" Value="2" />
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}">
                                        <ContentPresenter />
                                    </CheckBox>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </Setter.Value>
            </Setter>
        </Style>
        <ListBox 
            x:Name="lbVP"
            Grid.Row="2" 
            Background="Transparent"
            Style="{StaticResource CheckBoxListStyle}"
            ItemsSource="{Binding ListVP}" Margin="26,0,2,0">            
        </ListBox>
 
        <ListBox 
            x:Name="lbCVP"// листбокс куда надо записывать значения выделенных чекбоксов 
            Grid.Row="2" 
            Background="Transparent"
            Margin="26,0,2,0">            
        </ListBox>
C#
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public ObservableCollection<ValP> ListVP { get; set; }
 
        public class ValP
        {
            public string NameVP { get; set; }
            public bool CheckedVP { get; set; }
        }
 
        public void ListBoxVP()
        {
            ListVP = new ObservableCollection<ValPara>();
            ListVP.Add(new ValP { NameVP = "VP1", CheckedVP = true });
            ListVP.Add(new ValP { NameVP = "VP2", CheckedVP = false });
            ListVP.Add(new ValP { NameVP = "VP3", CheckedVP = false });
            ListVP.Add(new ValP { NameVP = "VP4", CheckedVP = false });
            ListVP.Add(new ValP { NameVP = "VP5", CheckedVP = false });
            ListVP.Add(new ValP { NameVP = "VP6", CheckedVP = false });
            ListVP.Add(new ValP { NameVP = "VP7", CheckedVP = false });
            this.DataContext = this;
        }
и все в ступоре. гуггл не дает нормального ответа. заранее буду благодарен.
если можно короткий пример.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.02.2020, 08:09
Ответы с готовыми решениями:

Сохранить значения value выделенных чекбоксов
Привет. Есть таблица (список). Каждый элемент можно выбрать с помощью чекбокса. По клику на чекбокс появляются ссылки (удалить,...

Отслеживание выбранных чекбоксов
есть 6 чекбоксов. При нажатии на каждый отображается соответствующая палата. Как отследить какие чекбоксы выбраны и если выбраны, к...

Удаление выбранных чекбоксов
Привет. Есть вот такой скрипт: function selectAll() { var blnChecked =...

18
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 12:40
Цитата Сообщение от mabia Посмотреть сообщение
На WPF только начинаю переходить. Просьба не ругать.
В WinForm все было понятно.
Ругать не буду, но прокоментирую.
То как вы делали (и, наверное, продолжаете делать) на WF (WinForms) - ни есть хорошо.

Надо разделять Данные и их Представление. WF появился очень давно и поэтому там нет явного разделения этих понятий.
Что, к сожалению, привело к массовому неправильному его использованию и испортило стиль программирования очень и очень многих.

Поэтому то как вы делали - возможно в WF. Но это пример очень плохого, ущербного кода.

WPF же создавался гораздо позже. Создавался специально как инструмент реализации View в паттерне MVVM. В нём уже явно разделено Представление данных и сами Данные, которые передаются в DataContext (Контекст Данных).

В данном случае в вашей задаче, допустим, не ясно само её условие.
Второй ListBox выводит отмеченные элементы первого.
Это нужно Представлению (то есть интерфейсу пользователя)?
Или отметка элементов должна изменить Данные и второй ListBox должен отобразить это изменение данных?

Чуть позже скину пару примеров.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 13:41
Цитата Сообщение от mabia Посмотреть сообщение
Есть N чекбоксов и чекбокс
ВЫБРАТЬ ВСЕ. имя чекбоксов cbVP1, cbVP2 ... cbVP32
cboxOnOffAll имя чекбокса ВЫБРАТЬ ВСЕ реализация на
Оба варианта даю из соображения, что выделение элементов это методы Представления и к изменению самих Данных отношения не имеют.

Во первых, в типе предназначенном для использования в Представление должен реализовываться INPC.
Возьмите базовую реализацию отсюда Новая реализация OnPropertyChangedClass [WPF, Элд Хасп].
И запишите её в пространство Common.

Сам тип для Представления элемента Данных
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
using Common;
 
namespace ListBoxChecBoxMabia
{
    /// <summary>Тип для представления Данных</summary>
    public class ValP : OnPropertyChangedClass
    {
        private string _nameVP;
        private bool _checkedVP;
 
        public string NameVP { get => _nameVP; set => SetProperty(ref _nameVP, value); }
        public bool CheckedVP { get => _checkedVP; set => SetProperty(ref _checkedVP, value); }
    }
}
ViewModel которая используется для Контекста Данных
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
using Common;
using System.Collections.ObjectModel;
 
namespace ListBoxChecBoxMabia
{
 
    /// <summary>ViewModel для Контекста Данных Представления</summary>
    public class ViewModelV1 : OnPropertyChangedClass
    {
        /// <summary>Свойство-список для Представления</summary>
        public ObservableCollection<ValP> ListVP { get; }
            = new ObservableCollection<ValP>();
 
        public ViewModelV1()
        {
            /// Данные должнвы получаться из Модели
            /// Но для упрощения создаём их в Конструкторе.
            /// Такое допустимо только для Контекста Данных Времени Конструирования!
 
            ListVP.Add(new ValP { NameVP = "VP1", CheckedVP = true });
            ListVP.Add(new ValP { NameVP = "VP2", CheckedVP = false });
            ListVP.Add(new ValP { NameVP = "VP3", CheckedVP = false });
            ListVP.Add(new ValP { NameVP = "VP4", CheckedVP = false });
            ListVP.Add(new ValP { NameVP = "VP5", CheckedVP = false });
            ListVP.Add(new ValP { NameVP = "VP6", CheckedVP = false });
            ListVP.Add(new ValP { NameVP = "VP7", CheckedVP = false });
        }
    }
}
В окне устанавливаем Контекст Данных
XML
10
11
12
    <Window.DataContext>
        <local:ViewModelV1/>
    </Window.DataContext>
Так как второй список это отфильтрованное представление исходного списка, то типовой реализацией такой фильтрации в WPF это будет использование CollectionViewSorce
XML
13
14
15
16
17
18
19
20
21
    <Window.Resources>
        <CollectionViewSource x:Key="FilteredValP"
                              Source="{Binding ListVP}"
                              IsLiveFilteringRequested="True" Filter="CollectionViewSource_Filter">
            <CollectionViewSource.LiveFilteringProperties>
                <sys:String>CheckedVP</sys:String>
            </CollectionViewSource.LiveFilteringProperties>
        </CollectionViewSource>
    </Window.Resources>
C#
19
20
21
22
23
        /// <summary>Обработчик события фильтрации</summary>
        private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
        {
            e.Accepted = ((ValP)e.Item).CheckedVP;
        }
Выделения в ListBox вы не используете, поэтому заменил их на ItemsControl.
Так как взаимодействие между CheckBox для всех и в элементах носит локальный характер для Представления, то использовал в них обработчики Checked и Unchecked

Целиком XAML и CB (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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<Window x:Class="ListBoxChecBoxMabia.ListBoxVpV1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListBoxChecBoxMabia"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="ListBoxVpV1" Height="450" Width="800">
    <Window.DataContext>
        <local:ViewModelV1/>
    </Window.DataContext>
    <Window.Resources>
        <CollectionViewSource x:Key="FilteredValP"
                              Source="{Binding ListVP}"
                              IsLiveFilteringRequested="True" Filter="CollectionViewSource_Filter">
            <CollectionViewSource.LiveFilteringProperties>
                <sys:String>CheckedVP</sys:String>
            </CollectionViewSource.LiveFilteringProperties>
        </CollectionViewSource>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <CheckBox x:Name="checkBoxAll" Margin="20" Content="Выбрать все" 
                      Checked="CheckBox_Checked" Unchecked="CheckBox_UnChecked"/>
            <ItemsControl Grid.Row="1"
            ItemsSource="{Binding ListVP}"
            Margin="10">
                <ItemsControl.ItemTemplate>
                    <DataTemplate DataType="{x:Type local:ValP}">
                        <CheckBox Margin="5" Content="{Binding NameVP}" IsChecked="{Binding CheckedVP}" 
                                  Checked="ListCheckBox_Checked" Unchecked="ListCheckBox_Checked"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
 
        </Grid>
        <ItemsControl Grid.Column="1"
                 ItemsSource="{Binding Mode=OneWay, Source={StaticResource FilteredValP}}" 
                 DisplayMemberPath="NameVP"/>
    </Grid>
</Window>
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Data;
 
namespace ListBoxChecBoxMabia
{
    /// <summary>
    /// Логика взаимодействия для ListBoxVpV1.xaml
    /// </summary>
    public partial class ListBoxVpV1 : Window
    {
        public ListBoxVpV1()
        {
            InitializeComponent();
        }
 
        /// <summary>Обработчик события фильтрации</summary>
        private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
        {
            e.Accepted = ((ValP)e.Item).CheckedVP;
        }
        /// <summary>Флаг изменения состояния в Code Behind (CB)
        /// для избежания зацикливания</summary>
        private bool IsCheckedInCB;
 
        /// <summary>Установка всех в <see langword="true"/></summary>
        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (IsCheckedInCB)
                return;
            IsCheckedInCB = true;
 
            foreach (ValP val in ((ViewModelV1)DataContext).ListVP)
                val.CheckedVP = true;
 
            IsCheckedInCB = false;
        }
 
        /// <summary>Сброс всех к <see langword="false"/></summary>
        private void CheckBox_UnChecked(object sender, RoutedEventArgs e)
        {
            if (IsCheckedInCB)
                return;
            IsCheckedInCB = true;
 
            foreach (ValP val in ((ViewModelV1)DataContext).ListVP)
                val.CheckedVP = false;
 
            IsCheckedInCB = false;
        }
 
        private void ListCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (IsCheckedInCB)
                return;
            IsCheckedInCB = true;
 
            IEnumerable<ValP> list = ((ViewModelV1)DataContext).ListVP;
            bool first = list.First().CheckedVP;
 
            if (list.All(val => val.CheckedVP == first))
                checkBoxAll.IsChecked = first;
            else
                checkBoxAll.IsChecked = null;
 
 
            IsCheckedInCB = false;
        }
    }
}
0
1 / 1 / 0
Регистрация: 15.08.2016
Сообщений: 58
28.02.2020, 13:56  [ТС]
Второй ListBox выводит отмеченные элементы первого
но и при этом может удалят их этого списка элементы,
которые были отмечены а потом с них сняты галочки.
Т.е. список должен формироваться динамически.
Это не нужно Представлению. Второй ListBox должен
просто отобразить эти данные для их дальнейшего использования.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 14:05
Цитата Сообщение от mabia Посмотреть сообщение
если можно короткий пример.
Так как выделение нужно только в View, то для него можно воспользоваться уже имеющимся Мультиселктом в ListBox.
Тогда нем не нужен дополнительный тип для представления данных.
И второй ItemsControl мы привязываем к свойству SelectedItems (не путать с SelectedItem!) первого ListBox.
CollectionViewSource становится не нужной.

ViewModel
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
using Common;
using System.Collections.ObjectModel;
 
namespace ListBoxChecBoxMabia
{
    /// <summary>ViewModel для Контекста Данных Представления</summary>
    public class ViewModelV2 : OnPropertyChangedClass
    {
        /// <summary>Свойство-список для Представления</summary>
        public ObservableCollection<string> ListVP { get; }
            = new ObservableCollection<string>();
 
        public ViewModelV2()
        {
            /// Данные должнвы получаться из Модели
            /// Но для упрощения создаём их в Конструкторе.
            /// Такое допустимо только для Контекста Данных Времени Конструирования!
 
            ListVP.Add("VP1");
            ListVP.Add("VP2");
            ListVP.Add("VP3");
            ListVP.Add("VP4");
            ListVP.Add("VP5");
            ListVP.Add("VP6");
            ListVP.Add("VP7");
        }
    }
}
XAML и CB Окна
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
33
34
35
36
37
38
39
40
41
<Window x:Class="ListBoxChecBoxMabia.ListBoxVpV2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListBoxChecBoxMabia"
        mc:Ignorable="d"
        Title="ListBoxVpV2" Height="450" Width="800">
    <Window.DataContext>
        <local:ViewModelV2/>
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <CheckBox x:Name="checkBoxAll" Margin="20" Content="Выбрать все" 
                      Checked="CheckBox_Checked" Unchecked="CheckBox_UnChecked"/>
            <ListBox x:Name="listBox" Grid.Row="1"
                SelectionMode="Multiple"
                ItemsSource="{Binding ListVP}"
                Margin="10">
                <ListBox.ItemTemplate>
                    <DataTemplate DataType="{x:Type local:ValP}">
                        <CheckBox Margin="5" Content="{Binding}"
                                  IsChecked="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" 
                                  Checked="ListCheckBox_Checked" Unchecked="ListCheckBox_Checked"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
 
        </Grid>
        <ItemsControl Grid.Column="1"
                 ItemsSource="{Binding SelectedItems, ElementName=listBox}"/>
    </Grid>
</Window>
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System.Windows;
using System.Windows.Data;
 
namespace ListBoxChecBoxMabia
{
    /// <summary>
    /// Логика взаимодействия для ListBoxVpV1.xaml
    /// </summary>
    public partial class ListBoxVpV2 : Window
    {
        public ListBoxVpV2()
        {
            InitializeComponent();
        }
 
        /// <summary>Обработчик события фильтрации</summary>
        private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
        {
            e.Accepted = ((ValP)e.Item).CheckedVP;
        }
        /// <summary>Флаг изменения состояния в Code Behind (CB)
        /// для избежания зацикливания</summary>
        private bool IsCheckedInCB;
 
        /// <summary>Установка всех в <see langword="true"/></summary>
        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (IsCheckedInCB)
                return;
            IsCheckedInCB = true;
 
            foreach (object item in listBox.Items)
                listBox.SelectedItems.Add(item);
 
            IsCheckedInCB = false;
        }
 
        /// <summary>Сброс всех к <see langword="false"/></summary>
        private void CheckBox_UnChecked(object sender, RoutedEventArgs e)
        {
            if (IsCheckedInCB)
                return;
            IsCheckedInCB = true;
 
            listBox.SelectedItems.Clear();
 
            IsCheckedInCB = false;
        }
 
        private void ListCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (IsCheckedInCB)
                return;
            IsCheckedInCB = true;
 
            if (listBox.SelectedItems.Count == 0)
                checkBoxAll.IsChecked = false;
            if (listBox.SelectedItems.Count == listBox.Items.Count)
                checkBoxAll.IsChecked = true;
            else
                checkBoxAll.IsChecked = null;
 
 
            IsCheckedInCB = false;
        }
    }
}
Коды обоих вариантов прилагаю в архиве
Вложения
Тип файла: 7z ListBoxChecBoxMabia.7z (2.3 Кб, 1 просмотров)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 14:06
Цитата Сообщение от mabia Посмотреть сообщение
Второй ListBox выводит отмеченные элементы первого
но и при этом может удалят их этого списка элементы,
которые были отмечены а потом с них сняты галочки.
Добавьте ItemTemplate такой же как в первом списке
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 14:14
Для первого варианта изменения только в 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<Window x:Class="ListBoxChecBoxMabia.ListBoxVpV1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListBoxChecBoxMabia"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="ListBoxVpV1" Height="450" Width="800">
    <Window.DataContext>
        <local:ViewModelV1/>
    </Window.DataContext>
    <Window.Resources>
        <CollectionViewSource x:Key="FilteredValP"
                              Source="{Binding ListVP}"
                              IsLiveFilteringRequested="True" Filter="CollectionViewSource_Filter">
            <CollectionViewSource.LiveFilteringProperties>
                <sys:String>CheckedVP</sys:String>
            </CollectionViewSource.LiveFilteringProperties>
        </CollectionViewSource>
        <DataTemplate DataType="{x:Type local:ValP}">
            <CheckBox Margin="5" Content="{Binding NameVP}" IsChecked="{Binding CheckedVP}" 
                                  Checked="ListCheckBox_Checked" Unchecked="ListCheckBox_Checked"/>
        </DataTemplate>
 
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <CheckBox x:Name="checkBoxAll" Margin="20" Content="Выбрать все" 
                      Checked="CheckBox_Checked" Unchecked="CheckBox_UnChecked"/>
            <ItemsControl Grid.Row="1"
            ItemsSource="{Binding ListVP}"
            Margin="10"/>
 
        </Grid>
        <ItemsControl Grid.Column="1"
                 ItemsSource="{Binding Mode=OneWay, Source={StaticResource FilteredValP}}"/>
    </Grid>
</Window>
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 14:40
Для второго варианта XAMl и CB
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<Window x:Class="ListBoxChecBoxMabia.ListBoxVpV2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListBoxChecBoxMabia"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="ListBoxVpV2" Height="450" Width="800">
    <Window.DataContext>
        <local:ViewModelV2/>
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <CheckBox x:Name="checkBoxAll" Margin="20" Content="Выбрать все" 
                      Checked="CheckBox_Checked" Unchecked="CheckBox_UnChecked"/>
            <ListBox x:Name="listBox" Grid.Row="1"
                     SelectionMode="Multiple"
                     ItemsSource="{Binding ListVP}"
                     Margin="10"
                     SelectionChanged="listBox_SelectionChanged">
                <ListBox.ItemTemplate>
                    <DataTemplate DataType="{x:Type sys:String}">
                        <CheckBox Margin="5"
                      Content="{Binding}"
                      IsChecked="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" 
                      Checked="ListCheckBox_Checked" Unchecked="ListCheckBox_Checked"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
 
        </Grid>
        <ListBox x:Name="listBoxSelected" Grid.Column="1"
                SelectionMode="Multiple"
                ItemsSource="{Binding SelectedItems, ElementName=listBox}">
            <ListBox.ItemTemplate>
                <DataTemplate DataType="{x:Type sys:String}">
                    <CheckBox Margin="5"
                      Content="{Binding}"
                      IsChecked="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" 
                      Unchecked="ListCheckBoxSelected_UnChecked"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
 
namespace ListBoxChecBoxMabia
{
    /// <summary>
    /// Логика взаимодействия для ListBoxVpV1.xaml
    /// </summary>
    public partial class ListBoxVpV2 : Window
    {
        public ListBoxVpV2()
        {
            InitializeComponent();
        }
 
        /// <summary>Обработчик события фильтрации</summary>
        private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
        {
            e.Accepted = ((ValP)e.Item).CheckedVP;
        }
        /// <summary>Флаг изменения состояния в Code Behind (CB)
        /// для избежания зацикливания</summary>
        private bool IsCheckedInCB;
 
        /// <summary>Установка всех в <see langword="true"/></summary>
        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (IsCheckedInCB)
                return;
            IsCheckedInCB = true;
 
            foreach (object item in listBox.Items)
                listBox.SelectedItems.Add(item);
 
            IsCheckedInCB = false;
        }
 
        /// <summary>Сброс всех к <see langword="false"/></summary>
        private void CheckBox_UnChecked(object sender, RoutedEventArgs e)
        {
            if (IsCheckedInCB)
                return;
            IsCheckedInCB = true;
 
            listBox.SelectedItems.Clear();
 
            IsCheckedInCB = false;
        }
 
        private void ListCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (IsCheckedInCB)
                return;
            IsCheckedInCB = true;
 
            if (listBox.SelectedItems.Count == 0)
                checkBoxAll.IsChecked = false;
            else if (listBox.SelectedItems.Count == listBox.Items.Count)
                checkBoxAll.IsChecked = true;
            else
                checkBoxAll.IsChecked = null;
 
 
            IsCheckedInCB = false;
        }
 
        private void ListCheckBoxSelected_UnChecked(object sender, RoutedEventArgs e)
        {
            if (IsCheckedInCB)
                return;
            IsCheckedInCB = true;
 
            listBox.SelectedItems.Remove(((CheckBox)sender).DataContext);
 
            IsCheckedInCB = false;
        }
 
        private void listBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            foreach (object item in listBox.SelectedItems)
                listBoxSelected.SelectedItems.Add(item);
        }
    }
}
0
1 / 1 / 0
Регистрация: 15.08.2016
Сообщений: 58
28.02.2020, 15:17  [ТС]
может быть я совсем тупой. если можно
приведенный пример архивом проекта
в готовом виде можете скинуть. у меня
куча ошибок вылазит. Common пространство
имен не найдено и т.д
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 15:41
Цитата Сообщение от mabia Посмотреть сообщение
Common пространство
имен не найдено и т.д
Я же написал вам
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Во первых, в типе предназначенном для использования в Представление должен реализовываться INPC.
Возьмите базовую реализацию отсюда Новая реализация OnPropertyChangedClass [WPF, Элд Хасп].
И запишите её в пространство Common.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 16:02
Цитата Сообщение от mabia Посмотреть сообщение
сли можно
приведенный пример архивом проекта
в готовом виде можете скинуть. у меня
куча ошибок вылазит.
Архив собранного решения
Вложения
Тип файла: 7z ListBoxChecBoxMabiaSLN.7z (9.7 Кб, 1 просмотров)
0
1 / 1 / 0
Регистрация: 15.08.2016
Сообщений: 58
28.02.2020, 17:39  [ТС]
если я правильно понял. необходимо создать
3 папки Model ViewModel View
в Modelпоместить представление ValP.cs
в папку View поместить ListBoxVpV2 оба файла
в папку ViewModel файл ViewModelV2.cs
это правильно я понимаю?
а если мне надо без MVVM тогда как это сделать?

Добавлено через 14 минут
спасибо огромное все работает. только
во 2-м ListBox нужны только значения
а сами чекбоксы не нужны. их можно как-то
скрыть?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 18:10
Цитата Сообщение от mabia Посмотреть сообщение
спасибо огромное все работает. только
во 2-м ListBox нужны только значения
а сами чекбоксы не нужны. их можно как-то
скрыть?
Сделать можно только я не пойму как сочетать с
Цитата Сообщение от mabia Посмотреть сообщение
Второй ListBox выводит отмеченные элементы первого
но и при этом может удалят их этого списка элементы,
которые были отмечены а потом с них сняты галочки.

Объясните детальнее, точнее что вы хотите реализовать.

Добавлено через 3 минуты
Цитата Сообщение от mabia Посмотреть сообщение
а если мне надо без MVVM тогда как это сделать?
MVVM по любому будет присутствовать в WPF решении.
Другое дело что вы можете явно не выделять View, ViewModel, Model и тем самым себе значительно усложнить жизнь.

В WF тоже есть отдельно Данные и их Предствление. И то, что начинающие всё валят в одну кучу, только им же самим и осложнят создание приложений.
0
1 / 1 / 0
Регистрация: 15.08.2016
Сообщений: 58
28.02.2020, 18:22  [ТС]
сейчас все работает так.
любой отмеченный чекбокс из
первого ListBox автоматически
добавляется во второй ListBox
и автоматически удаляется,
если в 1м ListBox снята галочка.
необходимо сделать чтобы
выбранный чекбокс автоматически
добавлял (удалял) значение (VP1...VP7 )
выбранного чекбокса.

Добавлено через 1 минуту
второй чекбокс нужен только
для информации с ним не будет
никаких действий в интерфейсной
части. он как вспомогательный инструмент.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 18:52
Цитата Сообщение от mabia Посмотреть сообщение
второй чекбокс нужен только
для информации с ним не будет
никаких действий в интерфейсной
части. он как вспомогательный инструмент.
Ну так и было первоначально сделано, а потом вы написали
Цитата Сообщение от mabia Посмотреть сообщение
Второй ListBox выводит отмеченные элементы первого
но и при этом может удалят их этого списка элементы,
которые были отмечены а потом с них сняты галочки.
Добавлено через 6 минут
В первом варианте исправьте ItemsControl на такой
XML
44
45
46
        <ItemsControl Grid.Column="1"
                 ItemsSource="{Binding Mode=OneWay, Source={StaticResource FilteredValP}}"
                 DisplayMemberPath="NameVP"/>
Добавлено через 6 минут
Во втором варианте уберите обработчик в первом ListBox
XML
25
26
27
28
29
            <ListBox x:Name="listBox" Grid.Row="1"
                     SelectionMode="Multiple"
                     ItemsSource="{Binding ListVP}"
                     Margin="10">
                <!--SelectionChanged="listBox_SelectionChanged">-->
Замените второй ListBox на ItemsControl
XML
41
42
        <ItemsControl Grid.Column="1"
                 ItemsSource="{Binding SelectedItems, ElementName=listBox}"/>
И в CB уберите нижний обработчик
C#
79
80
81
82
83
        //private void listBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        //{
        //    foreach (object item in listBox.SelectedItems)
        //        listBoxSelected.SelectedItems.Add(item);
        //}
0
1 / 1 / 0
Регистрация: 15.08.2016
Сообщений: 58
28.02.2020, 18:57  [ТС]
огромная человеческая благодарность.
все работает как часы. просто песня.
где бы теперь все это прочесть.
сложно переходить с WF на WPF.
не могу понять BINDING.
пока разобрался только с ресурсами.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 19:41
Цитата Сообщение от mabia Посмотреть сообщение
где бы теперь все это прочесть.
MATANIT, professorweb
Есть темы в подписи моего поста.

Цитата Сообщение от mabia Посмотреть сообщение
сложно переходить с WF на WPF.
Сложно из-за того, что вы и WF неправильно использовали.
Приложения на нём должны быть в паттернах MVC, MVP и аналогичных.
Вы же сваливали всё в одну кучу в CB окна.
Это даже ООП не назовёшь, скорее процедурное программировние.

Умей вы создавать на WF нормальные приложения, переход на WPF проблем бы не вызвал.
Напротив, очень многое на WPF гораздо легче реализовывается.
0
1 / 1 / 0
Регистрация: 15.08.2016
Сообщений: 58
28.02.2020, 19:47  [ТС]
по сути имеется в ItemsControl переменный
массив значений из выбранных чекбоксов.
как мне можно обращаться теперь к этому
массиву? теперь же нет 2го листбокса.
к этому списку могу обратиться?
IEnumerable<ValP> list = ((ViewModelV1)DataContext).ListVP;
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16117 / 11238 / 2887
Регистрация: 21.04.2018
Сообщений: 33,039
Записей в блоге: 2
28.02.2020, 20:46
mabia, Вам нужно обрабатывать данные в ViewModel, а не в CB окна.
По нормальному надо использовать Behavior.
Один из вариантов Behavior для привязки свойств только для чтения [WPF, Элд Хасп]

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

Как переходной вариант от ПРОЦЕДУРНОГО программирования, попробуйте такую реализацию.

Объясняю на ВТОРОМ варианте

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

Для того чтобы вызвать это метод кнопкой надо объявить команду.
Команда получает может получить один параметр в типе object.

Команда состоит из двух методов.
Метод состояния команды возвращает true когда команду можно выполнить. В теле метода (созданным лямбдой) мы проверяем приводимость параметра к IEnumerable и наличии в нём хоть одной строки.

В исполнительном методе преобразуется параметр в последовательность строк и она передаётся в нужный метод.
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
42
43
44
45
46
47
48
49
50
51
52
using Common;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
 
namespace ListBoxChecBoxMabia
{
    /// <summary>ViewModel для Контекста Данных Представления</summary>
    public class ViewModelV2 : OnPropertyChangedClass
    {
 
        /// <summary>Свойство-список для Представления</summary>
        public ObservableCollection<string> ListVP { get; }
            = new ObservableCollection<string>();
 
        public ViewModelV2()
        {
            /// Данные должнвы получаться из Модели
            /// Но для упрощения создаём их в Конструкторе.
            /// Такое допустимо только для Контекста Данных Времени Конструирования!
 
            ListVP.Add("VP1");
            ListVP.Add("VP2");
            ListVP.Add("VP3");
            ListVP.Add("VP4");
            ListVP.Add("VP5");
            ListVP.Add("VP6");
            ListVP.Add("VP7");
 
 
            /// Инициализация комнды
            ConcatCommand = new RelayCommand
            (
                p => ConcatMetod(((IEnumerable)p).OfType<string>()),
                p => p is IEnumerable ie && ie.OfType<string>().Any()
            ); 
        }
 
        /// <summary>Команда соединяющая все выделенные значения</summary>
        public RelayCommand ConcatCommand { get; }
 
        private string _concatText;
        /// <summary>Свойство для выделенных значений</summary>
        public string ConcatText { get => _concatText; private set => SetProperty(ref _concatText, value); }
 
        /// <summary>Метод соединяющий строки в одну строку</summary>
        /// <param name="items">Последовательность строк</param>
        private void ConcatMetod(IEnumerable<string> items)
            => ConcatText = string.Join("; ", items);
    }
}
Теперь в XAML окна надо добавить кнопку привязанную к этой команде, а параметр команды в кнопке привязать к выделенной коллекции в ListBox.
И снизу под кнопкой добавим TextBlock для вывода полученного в методе значения.
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<Window x:Class="ListBoxChecBoxMabia.ListBoxVpV2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListBoxChecBoxMabia"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="ListBoxVpV2" Height="450" Width="800">
    <Window.DataContext>
        <local:ViewModelV2/>
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <CheckBox x:Name="checkBoxAll" Margin="20" Content="Выбрать все" 
                      Checked="CheckBox_Checked" Unchecked="CheckBox_UnChecked"/>
            <ListBox x:Name="listBox" Grid.Row="1"
                     SelectionMode="Multiple"
                     ItemsSource="{Binding ListVP}"
                     Margin="10">
                <ListBox.ItemTemplate>
                    <DataTemplate DataType="{x:Type sys:String}">
                        <CheckBox Margin="5"
                      Content="{Binding}"
                      IsChecked="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" 
                      Checked="ListCheckBox_Checked" Unchecked="ListCheckBox_Checked"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
 
        </Grid>
        <Grid Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <ItemsControl
                 ItemsSource="{Binding SelectedItems, ElementName=listBox}"/>
            <Button Grid.Row="1" Content="Соеденить выделенные элементы" Margin="5" Padding="5"
                    Command="{Binding ConcatCommand, Mode=OneWay}"
                    CommandParameter="{Binding SelectedItems, ElementName=listBox}"/>
            <TextBlock Grid.Row="2" Margin="10"
                       Text="{Binding ConcatText, Mode=OneWay}"/>
        </Grid>
 
    </Grid>
</Window>
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.02.2020, 20:46
Помогаю со студенческими работами здесь

Плагин отображения выбранных чекбоксов
Добрый день. Подскажите плагин на jquery, который бы показывал выбранные чекбоксы на странице в определенном диве. где-то на сайте...

Выполнение процедуры в зависимости от выбранных чекбоксов
Добрый день. Подскажите как условие сделать, нужно выполнить процедуру загрузки 2 файлов по условию: если стоит чекбокс 1 - загружаем...

Посчитать сумму в зависимости от выбранных чекбоксов
Приветствую уважаемые форумчане. В c# новичок, хочу попросить у вас помощи. Задача такова. Есть 10 checkbox'ов в зависимость от...

Подсчитывание количества значений в столбце выбранных чекбоксов
Есть таблица, в ней чекбоксы и цены, при выборе конкретных чекбоксов нужно записать итоговую сумму столбца цен. Пример: 1 чекбокс 20р 2...

Получить массив или строку из выбранных чекбоксов
Как после отправки формы, получить набор всех выбранных чек боксов? &lt;?=$f -&gt;field($form, 'type) -&gt;checkboxList();?&gt; ...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru