Загрузка списков внутри tabitems - какое событие использовать?

Допустим, у меня есть приложение, состоящее из одного окна. Внутри окна находится элемент управления вкладками с тремя элементами вкладки. Внутри каждой вкладки находится пользовательский элемент управления.

На одной вкладке у меня есть Добавить цвет. На следующей вкладке я добавил Fruit. На третьей вкладке у меня есть отношения, где пользователь может добавлять связи между фруктами и цветами. Эта связь отображается в списке, например:

Apple > Red
Pear  > Green

Ниже на той же вкладке у меня отсутствует список фруктов и список отсутствующих цветов ... то есть фрукты или цвета, которые были добавлены, но не связаны во взаимосвязи. Я должен объяснить, что все эти данные хранятся в трех отдельных текстовых файлах: fruit.txt, colors.txt и Relations.txt.

Проблема у меня в следующем. В настоящий момент заполнение списков и т. Д. Происходит по событию Usercontrol_loaded. Для фруктов / цветов это не имеет значения, так как после нажатия кнопки добавления список перезагружается. Проблема в экране отношений.

Допустим, пользователь запускает программу и щелкает вкладку отношений, чтобы увидеть, что связано. Мы скажем, что приведенный выше пример уже был в текстовом файле. Так что отношения проявляются - и никаких недостающих плодов. Затем пользователь щелкает вкладку фруктов и добавляет фрукт, а затем вкладку цвета и добавляет цвет. Затем переходит на вкладку отношений. Событие usercontrol_loaded уже произошло, поэтому эти два новых дополнения не отображаются в списках.

Если я перенесу код в событие GotFocus, пользователь не сможет сделать выбор в каком-либо списке, потому что он постоянно загружается, поскольку щелчок запускает событие.

Есть ли какое-либо другое событие или способ, которым я мог бы обновить это ТОЛЬКО, когда вкладка была «переключена на», кроме предоставления кнопки обновления?

Спасибо за чтение.

...

Редактировать 1: если я привязываю данные к списку недостающих фруктов, который я создаю в программном коде, у меня все равно остается та же проблема. Мне приходится перезагружать этот список каждый раз, когда они прыгают с этой вкладки и возвращаются к ней (потому что потенциально они добавили фрукт или цвет, которого сейчас нет).


person baron    schedule 23.02.2010    source источник


Ответы (3)


Вам нужно понимать, как работает MVVM и уведомление об изменениях. Вам не нужно использовать события или код программной части для всех, если вы отслеживаете все это в наблюдаемых коллекциях в классах модели представления, которые привязаны к пользовательскому интерфейсу.

Как предлагает wwosik, создайте класс, который предоставляет общедоступные свойства Colors, Fruits и Relationships, которые являются наблюдаемыми коллекциями. Поскольку он / она не предлагал, но, вероятно, должен был, также предоставить общедоступные MissingColors и MissingFruits наблюдаемые коллекции. Наконец, предоставьте доступ к общедоступным свойствам SelectedColor и SelectedFruit.

Создайте связанные элементы управления:

<ListBox ItemsSource="{Binding Colors}" SelectedItem="{Binding SelectedColor}"/>
<ListBox ItemsSource="{Binding Fruits}" SelectedItem="{Binding SelectedFruit}"/>
<ListBox ItemsSource="{Binding Relationships}"/>
<ListBox ItemsSource="{Binding MissingColors}"/>
<ListBox ItemsSource="{Binding MissingFruits}"/>

Реализуйте метод AddRelationship, который добавляет новую связь, состоящую из SelectedColor и SelectedFruit. Следует также удалить цвет и фрукты из соответствующих коллекций MissingColors и MissingFruits. Создайте команду, которая вызывает этот метод, и привяжите ее к чему-нибудь в пользовательском интерфейсе.

Вот и все. Неважно, на какой вкладке что-либо находится. Не имеет значения, в каком порядке пользователь просматривает вещи. Когда пользователь добавляет связь, фрукт или цвет, пользовательский интерфейс обновляется.

person Robert Rossney    schedule 24.02.2010
comment
Итак, я предполагаю, вы имеете в виду, что метод добавления фруктов / цветов изменяет списки отсутствующих фруктов / цветов. Мне также интересно, как строка {Binding Fruits} распознает, к какому классу принадлежит это свойство? Я предполагал, что они должны находиться в коде того, что пытается их отобразить, но из того, что я медленно понимаю из этих ответов, это определенно не так? ваше здоровье - person baron; 25.02.2010
comment
Я не просто подразумеваю это, я говорю это прямо (см. Предложение 2, абзац 4). Существует множество способов сообщить привязке, к какому классу принадлежит свойство, но, безусловно, самый простой - установить DataContext для любого объекта, содержащего все связанные элементы управления экземпляром класса. Если конструктор вашего класса инициализирует себя, это так же просто, как <object.DataContext><local:MyClass/></object.DataContext>. - person Robert Rossney; 25.02.2010

Вам необходимо привязать списки к данным из ViewModel. Таким образом, фреймворк WPF определяет момент, когда нужно обновить данные.

person Vlad    schedule 23.02.2010
comment
но есть логика, позволяющая определить, например, каких фруктов нет в файле отношений. Как вы связываете это - person baron; 24.02.2010
comment
вам понадобится отдельный список для них, поэтому вы привязываете пропавший фрукт к списку пропавших без вести. вам нужно будет обновлять списки всякий раз, когда изменяются некоторые данные: пользователь перезагружает данные или устанавливает дополнительные отношения и т. д. - person Vlad; 24.02.2010
comment
Тогда та же проблема! Логика проверки списка - куда он девается? Usercontrol_load - тогда список, к которому я привязываюсь, всегда один и тот же. GotFocus - тогда его нельзя выбрать. Если вы не говорите, что я должен выполнить привязку в xaml - на данный момент он у меня в UserControl_Loaded {listbox.ItemsSource = missingFruits; } missingFruits является ObservableCollection ‹string› - person baron; 24.02.2010
comment
Если я удалю код за источником элементов и установлю его в xaml следующим образом: ‹ListBox Name = listbox ItemsSource = {Binding missingFruits} /› это не сработает. Я люблю привязку данных. - person baron; 24.02.2010
comment
Серьезно, как только вы получите полное представление о привязке данных, вы начнете ей поклоняться. Я думал, что WPF невероятно сложен, прежде чем я понял привязку данных и MVVM; теперь я думаю, что это удивительно просто. - person Robert Rossney; 25.02.2010

WPF - это не WinForms. Вы не заполняете ListBoxs самостоятельно.

У вас есть

class MyData{
   ObservableCollection<Color> Colors;
   ObservableCollection<Fruit> Fruits;
   ObservableCollection<Pairs> Pairs;

   public void MatchCurrentSelection(){
        var selectedColor = CollectionViewSource.GetDefaultView(Colors).CurrentItem;
        var selectedFruit = CollectionViewSource.GetDefaultView(Fruits).CurrentItem;
        if(selectedColor != null && selectedFruit != null){
             Colors.Remove(selectedColor);
             Fruits.Remove(selectedFruit);
             Pairs.Add(new Pair(selectedColor, selectedFruit));
        }
   }
} 

ListBoxes

<ListBox ItemsSource="{Binding Colors}" IsSynchronizedWithCurrentItem="true"/>
<ListBox ItemsSource="{Binding Fruits}" IsSynchronizedWithCurrentItem="true"/>
<ListBox ItemsSource="{Binding Pairs}"/>
person user76035    schedule 23.02.2010