Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WPF, Silverlight Новый топик    Ответить
 WPF + EF биндинг к текстбоксу  [new]
володька трынькин
Member

Откуда:
Сообщений: 141
Коллеги, добрый день
начинаю осваивать связку WPF и EF. возникла такая трудность. возможно задача довольно банальная, но решения я пока не нашел
в гуи приложения есть датагрид и набор текстбоксов и др. - редактор данных. также кнопки Создать, Обновить, Удалить. все просто!
текстбоксы прибиндены к выделенной строке в гриде. т.е. пользователь выделяет строку в гриде - заполняются поля редактора, далее пользователь может в них что-то изменить. и потом при нажатии на Создать, будет создана новая сущность и добавлена в базу, либо Обновить - обновится в базе существующая сущность. Вопрос в том как прибиндить контролы к двум объектам, чтобы при изменении в них значений - менялись свойства и нового объекта, и существующего (выделенного)
6 май 14, 09:06    [15977220]     Ответить | Цитировать Сообщить модератору
 Re: WPF + EF биндинг к текстбоксу  [new]
володька трынькин
Member

Откуда:
Сообщений: 141
немного поясню.
во всех просмотренных аналогичных примерах работа происходит так:
выделяется строка в гриде, далее редактируются поля редактора и обновление в базе происходит либо сразу при изменении, либо по нажатию какой-либо кнопки. а вот для создания новой записи бд по нажатию кнопки поля редактора сначала очищаются - при этом создается новый объект, а потом заполняются данными. и заносится в бд.
у меня же после выделения строки и редактирования полей заранее неизвестно, что будет делать пользователь - изменять существующую запись, либо захочет новую создать.
6 май 14, 23:54    [15983109]     Ответить | Цитировать Сообщить модератору
 Re: WPF + EF биндинг к текстбоксу  [new]
user7320
Member

Откуда:
Сообщений: 3543
Но пользователь же должен как-то определиться - новую или существующую? Значит, это будут либо две кнопки, либо два разных нажатия на клавиатуре. Вот и биндть разные команды (или что там у тебя) на разные действия.

Т. е. юзер редактирует существующую строку, а затем выбирает действие - новую создать или существующую изменить. Когда юзер редактирует существующую, ты её выделяешь в отдельный объект и юзер редактирует на самом деле копию. Потом копия либо заменяет старую, либо вставляется как новая.

Это как вариант.
7 май 14, 10:32    [15984000]     Ответить | Цитировать Сообщить модератору
 Re: WPF + EF биндинг к текстбоксу  [new]
user7320
Member

Откуда:
Сообщений: 3543
Зачем ты хочешь позвоить юзеру вставить старую отредактированную запись как новую? Наверняка, для удобства - чтобы юзер не заполнял заново одинаковые поля. Тогда у тебя примерно та же байда, что и у меня. Там много воды, но в конце мы договорились до некоего решения. Суть его - если старый объект вставляется как новый, то старый объект копируется.
7 май 14, 10:37    [15984024]     Ответить | Цитировать Сообщить модератору
 Re: WPF + EF биндинг к текстбоксу  [new]
user7320
Member

Откуда:
Сообщений: 3543
У меня копирование сделано в виде расширения для типа Object, который является базовым для всех ссылочных типов. Для типов-начений можно обычным MemberwiseClone пользоваться. Расширение просто сериализует объект в бинарный формат и затем десериализует его:

    public static class ObjectExtensions
    {
        public static T DeepClone<T>(this T obj)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, obj);
                ms.Position = 0;
                return (T)bf.Deserialize(ms);
            }
        }
    }


Осталось только расставить в твоём типе атрибуты сериализации.
7 май 14, 10:43    [15984065]     Ответить | Цитировать Сообщить модератору
 Re: WPF + EF биндинг к текстбоксу  [new]
володька трынькин
Member

Откуда:
Сообщений: 141
поскольку мне нужно копировать только все свойства объекта, редактируемые пользователем, то я решил использовать их атрибуты

        public void CloneProperties(EntityObject source, EntityObject destination)
        {
            // все свойства объекта
            PropertyInfo[] propertyInfos = source.GetType().GetProperties();

            // свойства с нужым атрибутом
            var attProperties = propertyInfos.Where(prop => prop.IsDefined(typeof (EdmScalarPropertyAttribute), false));
            
            foreach (PropertyInfo attProperty in attProperties)
            {
                attProperty.SetValue(destination, attProperty.GetValue(source, null), null);
            }
        }


но теперь у меня другая проблема появилась. раньше я биндил контролы редактора к выделенной в гриде строке. но тогда получается, как только редактируешь контролы - меняется и строка в гриде сразу же. мне это не надо.
как организовать, чтобы контролы биндились к свойствам объектам, который создается при смене строки.
поясню.
DataContext окна есть некий MyViewModel (реализующий INotifyPropertyChanged)
у датагрида:
SelectedItem="{Binding MySelectedEntity}"

и тогда логично, что все контролы нужно прибиндить к соответствующим свойствам этого MySelectedEntity.
пробую например так
                <TextBox  Text="{Binding MySelectedEntity.Descr, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
                </TextBox>

не работает.
во всех примерах встречал, что нужно во ViewModel прописывать отдельно все свойства из объекта ентити. но как-то не комильфо. их куча. есть ли проще способ?
8 май 14, 01:52    [15988598]     Ответить | Цитировать Сообщить модератору
 Re: WPF + EF биндинг к текстбоксу  [new]
user7320
Member

Откуда:
Сообщений: 3543
Выдели отдельный объект для редактирования.
8 май 14, 05:01    [15988648]     Ответить | Цитировать Сообщить модератору
 Re: WPF + EF биндинг к текстбоксу  [new]
user7320
Member

Откуда:
Сообщений: 3543
Например. Вытаскиваем из источника выбранный для редактирования объект (модель) в отдельную вью модель и вью. Редактируем. Возвращаем в источник. Источник же прибинден к датагриду? - Тогда датагрид обновит своё содержимое, чтобы изменения источника отобразились.
8 май 14, 05:04    [15988649]     Ответить | Цитировать Сообщить модератору
 Re: WPF + EF биндинг к текстбоксу  [new]
володька трынькин
Member

Откуда:
Сообщений: 141
а что значит вытаскиваем в отдельную вью-модель?
ведь в объект MySelectedEntity уже реализован INotifyPropertyChanged. почему тогда я просто не могу для грида, в котором накиданы все контролы редактора, указать DataContext = MySelectedEntity. и биндить к контролам свойства объекта(например, Descr)
8 май 14, 18:11    [15992912]     Ответить | Цитировать Сообщить модератору
 Re: WPF + EF биндинг к текстбоксу  [new]
володька трынькин
Member

Откуда:
Сообщений: 141
внезапно!
нашел свой косяк в коде. во вью-модель, в сеттере MySelectedEntity не вызывался OnPropertyChanged.
теперь все заработало. видимо, получится без дополнительных Вью и ВьюМоделей
8 май 14, 18:40    [15992984]     Ответить | Цитировать Сообщить модератору
 Re: WPF + EF биндинг к текстбоксу  [new]
user7320
Member

Откуда:
Сообщений: 3543
автор
ведь в объект MySelectedEntity уже реализован INotifyPropertyChanged. почему тогда я просто не могу для грида, в котором накиданы все контролы редактора, указать DataContext = MySelectedEntity. и биндить к контролам свойства объекта(например, Descr)

А, у тебя уже есть отдельный объект для редактирования. Что-то я пропустил... Ну байндь тогда.

автор
во всех примерах встречал, что нужно во ViewModel прописывать отдельно все свойства из объекта ентити. но как-то не комильфо. их куча. есть ли проще способ?

А по-другому это как? Ты можешь прибайндить сразу объект EF к контролам. А можешь сделать промежуточную вью модель. Но модель же как-то должна устанавливать свой свойства? Покажи код этой модели.

Прописывай во вью модели только те свойства из объекта энтити, которые тебе нужны. И байндь ко вью только их, соответсвтенно.
8 май 14, 18:48    [15992997]     Ответить | Цитировать Сообщить модератору
Все форумы / WPF, Silverlight Ответить