Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > WPF, UWP, WinRT, XAML
Регистрация

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

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.03.2016, 22:31   #1
spiri
 
Регистрация: 30.04.2012
Сообщений: 8
По умолчанию 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, 22:37   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

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

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

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

Цитата:
ArrayList
Зачем он в .NET выше 1.1?
Есть же List<T>
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

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

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

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

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

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

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

Для начала можно например на библиотеку MvvmLight посмотреть. Там в основном просто вспомогательные классы упрощающие работу без принуждения к чему-либо.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 31.03.2016, 11:22   #5
spiri
 
Регистрация: 30.04.2012
Сообщений: 8
По умолчанию

Создал форму, загрузил данные в коллекцию 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, 12:19   #6
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
А вот как дальше связать 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();
            }
        }
    }
}
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

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

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

http://reedcopsey.com/2010/01/07/bet...wpf-with-mvvm/
http://www.mvvmlight.net/doc/
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 20.04.2016, 22:44   #9
spiri
 
Регистрация: 30.04.2012
Сообщений: 8
По умолчанию

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


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


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