Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > .NET > WPF, UWP, WinRT, XAML
Регистрация

Восстановить пароль
Повторная активизация e-mail

Ответ
 
Опции темы
Старый 28.03.2016, 23:31   #1
spiri
 
Регистрация: 30.04.2012
Сообщений: 8
Репутация: 10
По умолчанию WPF и ADO.net

Пишу диплом, база данных отдела кадров на c# и MSSQL server. На WinForms делаю подобные программы без особых трудностей, на мой взгляд там все логично и понятно. Сейчас дипломный руководитель хочет, чтобы я использовал технологию wpf. В итоге столкнулся с несколькими трудностями почти в самом начале:
Какую технологию доступа к базе выбрать? Я хотел ограничиться простыми запросами. Через dataReader сделал выборку из четырёх таблиц и записал полученную таблицу в ArrayList, в коде .cs присвоил DataGrid.ItemSource мой ArrayList и в xaml коде связал каждый столбец с соответствующим полем таблицы. Здесь все получилось. В DataGrid краткая информация, для выделенной строки нужно остальные поля отобразить в соответствующих TextBox-ах на этой же форме. Вот так и не понял как это сделать. Можно ли с таблицей dataGrid работать так же как в ВинФормс, как с двумерным массивом?
И это я ещё не пробовал записывать данные введённые на форме в базу SQL server, думаю тоже сюрпризы ждут. Пробовал EntityFramevork, тоже извращение какое-то на первый взгляд. Может ли кто-то посоветовать в каком направлении двигаться? Я не нашёл даже более-менее нормальную информацию по WPF, везде поверхностно разбирают Binding, EntityFramework и работу с БД, на примитивных простых примерах, а как это все реализовать на примерах чуть посложнее, где больше двух таблиц и больше функционал чем две кнопки, так и не нашёл.
spiri вне форума   Ответить с цитированием
Старый 28.03.2016, 23:37   #2
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 17,150
Репутация: 3316

icq: 512-765
skype: alexp.frl
По умолчанию

В WPF обычно используют биндинги, MVVM и т.п.

Просто прибиндите свой список к ДатаГрид (ItemsSource или типа того, и в столбцах указать свойства). Только обычно лучше использовать не обычный List, а хотя бы ObservableCollection например.
Для выбранного элемента тоже биндинг к SelectedItem или типа того (например завести отдельное свойство для этого, во ViewModel).

EntityFramework или обычный ADO.NET особой разницы нет для WPF, но вообще EF обычно проще/удобнее.

Цитата:
ArrayList
Зачем он в .NET выше 1.1?
Есть же List<T>

Последний раз редактировалось Alex11223; 28.03.2016 в 23:53.
Alex11223 на форуме   Ответить с цитированием
Старый 30.03.2016, 13:00   #3
spiri
 
Регистрация: 30.04.2012
Сообщений: 8
Репутация: 10
По умолчанию

Первое впечатление от mvvm и EntityFramework, что это издевательство какое-то. Даже для простейшего приложения создаётся куча классов и требуется написать большое количество кода и вместо того, чтобы разрабатывать бизнес-логику приложения приходится большую часть времени тратить на интерфейс, на привязку, на реализацию классов и интерфейсов для взаимодействия элементов окна с данными. Конечно, если разобраться в материале, это все делается на автомате и проблем не возникает, но удобство в чем? WinForms морально устаревшая технология со своими недостатками, но писать на мой взгляд гораздо проще и удобней. Почему в wpf нельзя сделать что-то близкое к mvp? Есть данные, есть элементы интерфейса и через свои методы, свойства и поля они взаимодействуют друг с другом в слое бизнес-логики без множества лишних действий.
spiri вне форума   Ответить с цитированием
Старый 30.03.2016, 13:30   #4
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 17,150
Репутация: 3316

icq: 512-765
skype: alexp.frl
По умолчанию

mvvm и EntityFramework никак не связаны друг с другом. Можете и без EF читать/записывать данные самостоятельно.
Если вам нравится dataReader, то что мешает прочитать данные в коллекцию (List, ObservableCollection, ...) и прибиндить?

Цитата:
Почему в wpf нельзя сделать что-то близкое к mvp?
Почему нельзя?
Но в WPF есть фичи типа биндинга делающие использование MVVM более удобным.

Про преимущества и удобства зависит от реализации.

Что за классы и интерфейсы, на которые вы тратите кучу времени?

Для начала можно например на библиотеку MvvmLight посмотреть. Там в основном просто вспомогательные классы упрощающие работу без принуждения к чему-либо.
Alex11223 на форуме   Ответить с цитированием
Старый 31.03.2016, 12:22   #5
spiri
 
Регистрация: 30.04.2012
Сообщений: 8
Репутация: 10
По умолчанию

Создал форму, загрузил данные в коллекцию List<>, связал данные с dataGrid. А вот как дальше связать TextBox с соответствующим полем таблицы, и как правильно сделать обработчик события, чтобы при выделении другой записи, менялся текст в TextBox?


Видел пример, где связывали всю панель, содержащую данные через DataContext, у меня не получилось подобное. DataGrid получилось связать только в .cs файле.
PHP код:
<Window x:Class="Кадровый_учет.PersonaWindow"
        
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:Кадровый_учет"
        
mc:Ignorable="d"
        
Title="PersonaWindow" Height="550" Width="830">
    <
Grid Background="{StaticResource BackgroundWindowResource}">
        <
Grid.RowDefinitions>
            <
RowDefinition></RowDefinition>
            <
RowDefinition></RowDefinition>
            <
RowDefinition></RowDefinition>
            <
RowDefinition></RowDefinition>
            <
RowDefinition></RowDefinition>
            <
RowDefinition></RowDefinition>
            <
RowDefinition></RowDefinition>
        </
Grid.RowDefinitions>
        <
Grid.ColumnDefinitions>
            <
ColumnDefinition></ColumnDefinition>
            <
ColumnDefinition></ColumnDefinition>
            <
ColumnDefinition></ColumnDefinition>
        </
Grid.ColumnDefinitions>
        <
StackPanel Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3">
            <
Menu>
                <
MenuItem Header="Файл" />
            </
Menu>
            <
TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Text="Личная карточка сотрудника" 
                   
HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20"/>            
        </
StackPanel>
        <
StackPanel Grid.Column="0" Grid.Row="1" Grid.RowSpan="5">
            <
DataGrid Name="dg_Employee" AutoGenerateColumns="False" MaxWidth="300" MaxHeight="500"
                      
BorderBrush="#FF1F33EB" BorderThickness="3" IsReadOnly="True"
                      
RowHeight="25" Cursor="Hand" CanUserAddRows="False" CanUserDeleteRows="False" >
                <
DataGrid.Columns>
                    <
DataGridTextColumn Header="Фамилия" Binding="{Binding surname}"/>
                    <
DataGridTextColumn Header="Имя" Binding="{Binding name}" />
                    <
DataGridTextColumn Header="Отчество" Binding="{Binding patronymic}"/>
                    <
DataGridTextColumn Header="Отдел" Binding="{Binding depart_name}" />
                </
DataGrid.Columns>
            </
DataGrid>
        </
StackPanel>
        <
WrapPanel Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" DataContext="{Binding ElementName=dg_Employee, Path=SelectedItem}">
            <
TextBlock Text="Фамилия" Margin="15,0,5,5" FontWeight="Bold"/>
            <
TextBox Name="txb_surname" Text="{Binding surname}" MinWidth="70"/>
            <
TextBlock Text="Имя" Margin="10,0,5,5" FontWeight="Bold"/>
            <
TextBox Name="txb_name" Text="{Binding name}" MinWidth="70"/> 
        </
WrapPanel>
    </
Grid>
</
Window
PHP код:
public partial class PersonaWindow Window
    
{
        
Data data = new Data();
        public 
PersonaWindow()
        {
            
InitializeComponent();

            List<
DbDataRecordallEmploye data.GetAllEmployee();
            
dg_Employee.ItemsSource allEmploye;
        }

    } 
Данные загружаю в отдельном классе:
PHP код:
class Data
    
{
        
string connString = @"Data Source=MAXPC\SQLEXPRESS;Initial Catalog=КадровыйУчет;Integrated Security=True; Pooling=False"
                                  
        public List<
DbDataRecordGetAllEmployee()
        {
            List<
DbDataRecordallEmployee = new List<DbDataRecord>();
            
using (SqlConnection con = new SqlConnection(connString))
            {
                
SqlCommand com = new SqlCommand(@"SELECT surname, name, patronymic, birth_Date, 
                                                  sex, depart_name, post_name, room_number, telephone 
                                                  FROM Employee, Department, Room, Post 
                                                  WHERE Department.depart_ID = Employee.dept_ID 
                                                  AND Room.room_ID = Employee.room_ID 
                                                  AND Post.post_ID = Employee.post_ID ORDER BY name"
,con);
                try
                {
                    
con.Open();
                    
SqlDataReader dr com.ExecuteReader();

                    if (
dr.HasRows)
                        foreach (
DbDataRecord result in dr)
                            
allEmployee.Add(result);
                }
                catch
                {

                }
            }
            return 
allEmployee;
        }
    } 
spiri вне форума   Ответить с цитированием
Старый 31.03.2016, 13:19   #6
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 17,150
Репутация: 3316

icq: 512-765
skype: alexp.frl
По умолчанию

Цитата:
А вот как дальше связать TextBox с соответствующим полем таблицы
С выделенной строкой? SelectedItem, я ж сказал уже.

И еще желательно INotifyPropertyChanged использовать.

Цитата:
содержащую данные через DataContext, у меня не получилось подобное. DataGrid получилось связать только в .cs файле.
По-разному можно. Например в коде выставить нужный DataContext: DataContext = new Something() (но тогда в дизайнере не видно).

Или как-то так:
Код:

<Window x:Class="WpfApplication7.PersonListWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModel="clr-namespace:WpfApplication7.ViewModel"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <viewModel:PersonListViewModel/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            
            <TextBlock Text="Name:" Margin="3"/>
            <TextBox Grid.Column="1" Margin="3"
                     Text="{Binding SelectedPerson.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </Grid>
        
        <DataGrid Grid.Row="1" Margin="3" IsReadOnly="True" AutoGenerateColumns="False"
                  ItemsSource="{Binding People}" SelectedItem="{Binding SelectedPerson}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="*" />
                <DataGridTextColumn Header="Age" Binding="{Binding Age}" Width="50"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Код:

using System.Windows;
using WpfApplication7.ViewModel;

namespace WpfApplication7
{
    public partial class PersonListWindow : Window
    {
        private PersonListViewModel _viewModel;

        public PersonListWindow()
        {
            InitializeComponent();

            _viewModel = (PersonListViewModel) DataContext;
        }
    }
}

Код:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfApplication7
{
    /// <summary>
    /// A base class for objects of which the properties must be observable.
    /// </summary>
    public class ObservableObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

                                                          // .NET 4.5+  
        protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

Код:

using System;

namespace WpfApplication7.Model
{
    public class Person : ObservableObject
    {
        private string _name = String.Empty;
        public string Name
        {
            get
            { return _name; }
            set
            {
                _name = value;
                RaisePropertyChanged();
            }
        }

        private int _age = 0;
        public int Age
        {
            get
            { return _age; }
            set
            {
                _age = value;
                RaisePropertyChanged();
            }
        }
    }
}


Код:

using System.Collections.Generic;
using System.Linq;
using WpfApplication7.Model;

namespace WpfApplication7.ViewModel
{
    class PersonListViewModel : ObservableObject
    {
        public PersonListViewModel()
        {
            People = new List<Person>()
            {
                new Person() { Name = "Alice", Age = 19 },
                new Person() { Name = "Bob", Age = 21 },
                new Person() { Name = "Carol", Age = 20 }
            };

            SelectedPerson = People.FirstOrDefault();
        }

        private List<Person> _people = new List<Person>();
        public List<Person> People
        {
            get
            { return _people; }
            set
            {
                _people = value;
                RaisePropertyChanged();
            }
        }

        private Person _selectedPerson = null;
        public Person SelectedPerson
        {
            get
            { return _selectedPerson; }
            set
            {
                _selectedPerson = value;
                RaisePropertyChanged();
            }
        }
    }
}


Последний раз редактировалось Alex11223; 27.05.2016 в 09:16.
Alex11223 на форуме   Ответить с цитированием
Старый 01.04.2016, 19:41   #7
spiri
 
Регистрация: 30.04.2012
Сообщений: 8
Репутация: 10
По умолчанию

Вроде бы начал въезжать, но все-таки каша в голове какая-то и свой пример не могу пока реализовать, слишком много всего сразу нужно сделать даже для простейших действий. Не нашёл ни одного полноценного примера, где подобное реализовано по шагам с более-менее подробным объяснением для новичка, про то как с SelectedItem работать видел в одном примере только и то там без объяснения оставили.
spiri вне форума   Ответить с цитированием
Старый 01.04.2016, 19:53   #8
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 17,150
Репутация: 3316

icq: 512-765
skype: alexp.frl
По умолчанию

http://reedcopsey.com/2010/01/07/bet...wpf-with-mvvm/
http://www.mvvmlight.net/doc/
Alex11223 на форуме   Ответить с цитированием
Старый 20.04.2016, 23:44   #9
spiri
 
Регистрация: 30.04.2012
Сообщений: 8
Репутация: 10
По умолчанию

В итоге продвинулся в написании. Но я пока не могу использовать возможности wpf как надо, только байндинг где без него никак. Грубо говоря как и раньше использую императивный подход, декларативный только начинаю постигать.
Спасибо за помощь и за внимание))
spiri вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Тема для курсовой работы C#, WinForms, GDI++, ADO.NET, WPF. AIR_3 Помощь студентам 0 28.11.2012 17:23
WPF программист (C#, .Net Framework) lyubov_merkulova Работа на постоянной основе - Вакансии 0 18.07.2012 14:55
Программист (VB).NET+WPF gr1983 Фриланс 3 14.02.2011 08:11
Удаленный SQL-сервер Ado.Net + .Net remoting + Asp .Net gammaray Базы данных (ADO.NET, LinqToSql, ORM Entity Framework, NHibernate) 2 22.11.2010 18:36


19:00.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru