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

Динамическое обновление DataGrid

29.04.2023, 23:09. Показов 966. Ответов 2

Студворк — интернет-сервис помощи студентам
Решается следующая задача:

Есть приложение WPF, содержащее список функций (ListBox), значение коэффициентов A, B (TextBox), C (ComboBox) и таблицу со значениями: X, Y, F(X,Y).

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
<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
 
        <!-- Список с выбором функции -->
        <StackPanel Grid.Column="0" Margin="10">
            <Label Content="Функция" />
            <ListBox ItemsSource="{Binding FunctionNames}" 
                  SelectedItem="{Binding SelectedFunctionName}" 
                  Margin="0 5">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <Label Content="Коэффициент a" />
            <TextBox Text="{Binding A}" 
                     Margin="0 5"/>
            <Label Content="Коэффициент b" />
            <TextBox Text="{Binding B}" 
                     Margin="0 5"/>
            <Label Content="Коэффициент c" />
            <ComboBox ItemsSource="{Binding FunctionCoefficientsC}" 
                      SelectedItem="{Binding SelectedFunctionCoefficentC, Mode=TwoWay}" 
                      Margin="0 5"/>
        </StackPanel>
 
        <!-- Таблица с результатами -->
        <DataGrid Grid.Column="3" 
                  ItemsSource="{Binding Results}" 
                  AutoGenerateColumns="False" 
                  CanUserAddRows="True"
                  Margin="10">
            <DataGrid.Columns>
                <DataGridTextColumn Header="f(x, y)" 
                                    Binding="{Binding F, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                                    IsReadOnly="True" />
                <DataGridTextColumn Header="x" 
                                    Binding="{Binding X, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                <DataGridTextColumn Header="y" 
                                    Binding="{Binding Y, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
Модели для таблицы и всего остального:

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
 public class ResultItems : INotifyPropertyChanged
    {
        private double _f;
        private double _x;
        private double _y;
 
        public double F
        {
            get => _f;
            set
            {
                if (_f != value)
                {
                    _f = value;
                    OnPropertyChanged(nameof(F));
                }
            }
        }
 
        public double X
        {
            get => _x;
            set
            {
                if (_x != value)
                {
                    _x = value;
                    OnPropertyChanged(nameof(X));
                    OnPropertyChanged(nameof(F));
                }
            }
        }
 
        public double Y
        {
            get => _y;
            set
            {
                if (_y != value)
                {
                    _y = value;
                    OnPropertyChanged(nameof(Y));
                    OnPropertyChanged(nameof(F));
                }
            }
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
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
public class MathFunction 
    {
        private static readonly Dictionary<string, ObservableCollection<double>> _functionsAndCoefficients = new Dictionary<string, ObservableCollection<double>>
        {
            {"Линейная", new ObservableCollection<double>{1, 2, 3, 4, 5}},
            {"Квадратичная", new ObservableCollection<double>{10, 20, 30, 40, 50}},
            {"Кубическая", new ObservableCollection<double>{100, 200, 300, 400, 500}},
            {"4-й степени", new ObservableCollection<double>{1000, 2000, 3000, 4000, 5000}},
            {"5-й степени", new ObservableCollection<double>{10000, 20000, 30000, 40000, 50000}}
        };
 
        public static List<string> FunctionNames => _functionsAndCoefficients.Keys.ToList();
 
        public static ObservableCollection<double> GetFunctionCoefficients(string functionName)
        {
            if (_functionsAndCoefficients.TryGetValue(functionName, out var coefficients))
            {
                return coefficients;
            }
 
            return new ObservableCollection<double>();
        }
 
        public static double CalculateFunctionResult(string functionName, double x, double y, double a, double b, double c)
        {
            double result = 0;
 
            switch (functionName)
            {
                case "Линейная":
                    result = a * x + b * y + c;
                    break;
                case "Квадратичная":
                    result = a * x * x + b * y * y + c;
                    break;
                case "Кубическая":
                    result = a * x * x * x + b * y * y * y + c;
                    break;
                case "4-й степени":
                    result = a * x * x * x * x + b * y * y * y * y + c;
                    break;
                case "5-й степени":
                    result = a * x * x * x * x * x + b * y * y * y * y * y + c;
                    break;
            }
 
            return result;
        }
    }
Модель представления:

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public class MainViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<ResultItems> _results;
        public ObservableCollection<ResultItems> Results
        {
            get => _results;
            set
            {
                _results = value;
                OnPropertyChanged(nameof(Results));
                UpdateResultItems();
            }
        }
 
        private double _a;
        private double _b;
 
        private string _selectedFunctionName;
        private double _selectedFunctionCoefficentC;
 
        private ObservableCollection<double> _functionCoefficientsC;
 
        public ObservableCollection<double> FunctionCoefficientsC
        {
            get => _functionCoefficientsC;
            set
            {
                if (_functionCoefficientsC != value)
                {
                    _functionCoefficientsC = value;
                    OnPropertyChanged(nameof(FunctionCoefficientsC));
                }
            }
        }
 
        public double SelectedFunctionCoefficentC
        {
            get => _selectedFunctionCoefficentC;
            set
            {
                if (_selectedFunctionCoefficentC != value)
                {
                    _selectedFunctionCoefficentC = value;
                    OnPropertyChanged(nameof(SelectedFunctionCoefficentC));
                    UpdateResultItems();
                }
            }
        }
 
        public List<string> FunctionNames { get; }
        public string SelectedFunctionName
        {
            get => _selectedFunctionName;
            set
            {
                _selectedFunctionName = value;
                FunctionCoefficientsC = MathFunction.GetFunctionCoefficients(SelectedFunctionName);
                OnPropertyChanged(nameof(SelectedFunctionName));
                UpdateResultItems();
            }
        }
 
        public double A
        {
            get => _a;
            set
            {
                if (_a != value)
                {
                    _a = value;
                    OnPropertyChanged(nameof(A));
                    UpdateResultItems();
                }
            }
        }
 
        public double B
        {
            get => _b;
            set
            {
                if (_b != value)
                {
                    _b = value;
                    OnPropertyChanged(nameof(B));
                    UpdateResultItems();
                }
            }
        }
 
        public MainViewModel()
        {
            FunctionNames = MathFunction.FunctionNames;
            FunctionCoefficientsC = new ObservableCollection<double>();
            Results = new ObservableCollection<ResultItems>();
        }
 
        private void UpdateResultItems()
        {
            if (Results.Count > 0)
            {
                var lastItem = Results[Results.Count - 1];
                lastItem.F = MathFunction.CalculateFunctionResult(SelectedFunctionName, lastItem.X, lastItem.Y, A, B, SelectedFunctionCoefficentC);
            }
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
Задача в следующем:

Пользователь должен выбрать функцию, ввести коэффициенты, затем в таблицу ввести X, Y и на их основе F(x,y) должна расчитываться автоматически.

Проблема:

При выборе функции, вводе коэффициентов и X, Y, функция расчитывается автоматически только после последующего обновления одного из коэффициентов, но не при изменении X и Y. Как сделать так, чтобы при изменении X и Y, F(x,y) расчитывалась сразу, как после изменения коэффициентов?

К сожалению, обработчики событий использовать нельзя, поэтому я не знаю, как правильно это реализовать. Пожалуйста, помогите
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.04.2023, 23:09
Ответы с готовыми решениями:

DataGrid динамическое добавление строк
Я перехожу на WPF с Windows Forms. Аналогом DataGridView в данной технологии является DataGrid. Возникли следующие вопросы: 1) я задал...

Динамическое добавление колонок в DataGrid
Здравствуйте уважаемые форумчане. Как из кода добавить, скажем, два столбца в DataGrid? Есть вот такой код: DataGrid dg = new...

Динамическое количество столбцов в DataGrid MVVM
Подскажите, пожалуйста, как реализовать DataGrid c количеством столбцов, изменяющимся в зависимости от заданного значения, придерживаясь...

2
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,036
Записей в блоге: 2
30.04.2023, 09:02
Лучший ответ Сообщение было отмечено CodyLV как решение

Решение

Цитата Сообщение от CodyLV Посмотреть сообщение
Пользователь должен выбрать функцию, ввести коэффициенты, затем в таблицу ввести X, Y и на их основе F(x,y) должна рассчитываться автоматически.
Если правильно понял, функцию и коэффициенты вы меняете на уровне MainViewModel.
А Х и Y на уровне ResultItems, который является элементом коллекции MainViewModel.

В такой реализации ResultItems не сможет сам пересчитать своё значение поскольку у него нет информации о функции и коэффициентах.

Три основных способа решения:
1) Добавить в ResultItems свойства для функции и коэффициентов и при их изменении проходить циклом по Results и обновлять каждый элемент коллекции;

2) Прослушивать в MainViewModel изменения элементов и пересчитывать значение функции. Такая подписка будет автоматически делаться если заменить ObservableCollection<ResultItems> на BindingList<ResultItems>. Но тогда лучше сделать Results иммутабельным свойством (только для чтения);

3) Рассчитывать значение функции в мультиконвертере который будет привязан как к X-Y в ResultItems, так и к функции и коэффициентам в MainViewModel.
1
3 / 3 / 0
Регистрация: 08.10.2022
Сообщений: 22
30.04.2023, 22:25  [ТС]
Добрый день, Элд Хасп!
Спасибо за ответ. Я нашел ваш ответ на похожую тему, проанализировал его и переделал архитектуру приложения в более практичную.

Если кому-то когда-то пригодится (и вдруг выдаст мою тему, вместо уже имеющейся?):

Динамическое размещение объектов в DataGrid MVVM
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.04.2023, 22:25
Помогаю со студенческими работами здесь

Динамическое создание элементов Grid и DataGrid
Всем доброго вечера. Требуется помощь. Никак не получается сделать. Задача следующая. Есть набор данных следующего вида: ...

Динамическое размещение объектов в DataGrid MVVM
Имеется форма со списком функций, текстовыми полями для задания коэффициентов a, b, выпадающем списком для c коэффициента функции, таблица...

Обновление DataGrid
Вот у меня вывод DataGrid, при этом там находятся данные из двух таблиц. Как сделать тогда кнопку обновленя для DataGrid? Сделать запрос на...

Обновление Datagrid
Есть проблема... При нажатии на кнопку, всплывает окно с редактированием записи из datagrid...нужно после окончания редактирования...

Tabcontrol привязка к папкам и динамическое наполнение файлами в datagrid
Сразу опишу цель с которой не смог справиться самостоятельно (объясняю я очень плохо): Есть папка &quot;Profiles&quot; и в ней разные...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
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 - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru