Модераторы: gambit, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Биндинг в WPF 
:(
    Опции темы
Ghost_XIII
Дата 16.1.2008, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 15.1.2008

Репутация: нет
Всего: нет



Всем доброго времени суток smile 
Помогите решить вот такую вот проблему:

Есть 2 класса
Код

    public class DataItem : INotifyPropertyChanged
    {
        public uint ID
        {
        }

        public string Name
        {
        }

        public static bool operator ==(DataItem item1, DataItem item2)
        {
            return item1.Equals(item2);
        }

        public static bool operator !=(DataItem item1, DataItem item2)
        {
            return !item1.Equals(item2);
        }

        public override bool Equals(object obj)
        {
            DataItem temp = obj as DataItem;
            if (temp == null) return false;
            if (this.name == temp.name) return true;
            else return false;
        }
    }

    public class DataItemCollection : ObservableCollection<DataItem>
    {
        public DataItemCollection()
            : base()
        {
        }
    }

(чтобы съэкономить место я почти всё из них повыризал, оставив тока самое основное)

и ресурс окна
Код

    <Window.Resources>
        <l:DataItemCollection x:Key="Items" x:Name="Items"/>
    </Window.Resources>


Я этот ресурс биндю к ListBox
Код

        <ListBox Name="ViewBox" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="7" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                 ItemsSource="{DynamicResource ResourceKey=Items}" DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True"/>


и назначаю обработчик нажатия кнопки
Код

        private void AddBtn_Click(object sender, RoutedEventArgs e)
        {
            uint count = 0;
            DataItemCollection items = this.FindResource("Items") as DataItemCollection;
            count = (uint)items.Count;
            count++;
            DataItem newItem = new DataItem(count, string.Format("Item {0}", count));
            items.Add(newItem);
        }


Проблема заключается в следующем: после первого нажатия к списку нормально добавляестя повый элемент, а вот во время попытки добавить второй элемент почему то происходит вызов перегруженного оператора "==" при этом item1 - это первый элемент в списке (и пока единственный), а item2 вобще null. Самое интересное, что сравнение происходит в цикле. первый раз сравнивает item1 и null, а потом и вообще  null с null. 
В результате получается, что после второго нажатия на кнопку, прога выдаёт либо, что объект равен null, либо, если делать проверку на нулы - переполнение стека.

Всё нормально работает если:
1 - не связывать ListBox с ресурсом
2 - не перегружать оператор ==

Помогите плиз, а то я уже себе всю голову сломал smile 

PM   Вверх
tol05
Дата 16.1.2008, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 11
Всего: 170



я в WPF не гуру, а для того, чтобы проимитировать твою ситуацию нужно дебагать проект. Проект ты не выложил, писать его, стало быть, нужно нам самим...

Но по своему опыту работы с устаревшими технологиями  smile  (FW 2.0 я имею в виду) могу сказать следующее:
Цитата(Ghost_XIII @  16.1.2008,  14:14 Найти цитируемый пост)
Я этот ресурс биндю к ListBox
т.е. контрол связан с источником данных и отображает часть его содержимого. Ты меняешь содержимое контрола, а содержимое источника его данных - не меняешь. Это плохо. Контрол пытается отображать то, чего нет в его источнике данных.

Одним словом, попробуй в обработчике клика добавлять item не в сам листбокс, а в ресурс, к которому биндится листбокс.

P.S. ну а почему вызывается оператор "==" ?
Просто внутри ф-ции Add вызывается ф-ция

Цитата

internal static void ChangeValue(DataItemCollection col, DataItem oldValue, DataItem newValue)
{
    if (oldValue != newValue)
    {
        if ((newValue != null) && (newValue.parent != null))
        {
            throw new InvalidOperationException(SR.DataItem_IsAlreadyUsedForAnotherObject);
        }
        if (oldValue != null)
        {
            oldValue.MoveTo(null, null);
        }
        if (newValue != null)
        {
            newValue.MoveTo(col, col.parent.Container);
        }
    }
}

вот и все. Юзай рефлектор.


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
Ghost_XIII
Дата 16.1.2008, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 15.1.2008

Репутация: нет
Всего: нет



Собсна ресурс я и меняю
Цитата

            DataItemCollection items = this.FindResource("Items") as DataItemCollection;
            items.Add(newItem);


Меня не удивило, если бы оно (==) один раз вызывалось, но когда оно попадает в какой то непонятный цикл?

Прикладываю проект

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  ListViewTest.zip 15,07 Kb
PM   Вверх
Kefir
Дата 18.1.2008, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: нет
Всего: 87



у тебя плохо перегружен ==. там стоит item1.Equals(item2). Просто поправь так, чтобы учитывался вариант когда нули. Ну там if (item1 == null) return false; или что тебе там надо. А то оно бедное пытается у нуля вызвать ф-цию Equals. А це кидает ошибку что мол - я нуль и ни черта не умею. должно заработать.
PM MAIL WWW Skype   Вверх
Ghost_XIII
Дата 18.1.2008, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 15.1.2008

Репутация: нет
Всего: нет



Сразу же возникает вопрос - каково она вообще у нула вызывает == ?! но это наверное недостаток в моём образовании.

Ставил уже. Проверял все возможные нулы. Итог - стек оверфлоу. Так как она как зашла один раз в == так там и крутится пока не загнётся
PM   Вверх
Jlekc
Дата 18.1.2008, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 520
Регистрация: 10.2.2005
Где: Leopolis

Репутация: нет
Всего: 4



коректнее написать:
Код

public override bool Equals(object obj)
        {
            DataItem temp = obj as DataItem;
            if (object.Equals(temp, null)) return false;  // if (temp == null) return false;
            if (this.name == temp.name) return true;
            else return false;
        }




--------------------
PM MAIL ICQ   Вверх
Ghost_XIII
Дата 18.1.2008, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 15.1.2008

Репутация: нет
Всего: нет



Jlekc, Спасибо. Помогло.

Хотел спросить в чём разница между этими двумя строчками, но пока писал вопрос сам понял smile 

Я то думал, что она при добавлении нового элемента вызывает ==, а она оказывается вызывает Equals, что вполне естественно

Это сообщение отредактировал(а) Ghost_XIII - 18.1.2008, 12:38
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.0461 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.