2013-04-12 2 views
1

Я делаю приложение в C#, Windows Forms.C# - изменение дочернего элемента при изменении родителя

В этом приложении у меня есть основная форма, в которой есть несколько Элементов. Этот класс «Элемент» унаследован другими («ElementLabel», «ElementPicture», «ElementGraph»).

В какой-то момент мне может потребоваться изменить в режиме «партии» некоторое свойство нескольких элементов, в зависимости от того, что они есть. Например, я могу изменить свойство «Значение» всех выбранных элементов.

Проблема заключается, например, в том, что, когда свойство «Значение» изменяется в родительском классе, я также хочу изменить свойство «Текст» «Ярлык», которое существует в дочернем классе «ElementLabel». Я видел много тем об изменении родительского элемента через ребенка, но не иначе.

Я что-то упустил или у меня просто плохой дизайн, и ситуация вроде этого даже не должна произойти?

Заранее спасибо

+2

Похоже, что вы вводите в заблуждение наследование отношениями родитель-ребенок. Родитель-ребенок подразумевает * состав * не * наследование *. Пожалуйста, уточните, что вы имеете в виду, чтобы мы могли помочь вам лучше. – BinaryTox1n

+0

Это похоже на ['Ambient Property'] (http://msdn.microsoft.com/en-us/library/system.windows.forms.ambientproperties.aspx), который зависит от его родительского типа, Control.BackColor'. Это то, о чем вы думаете? –

ответ

1

Ну его трудно сказать, что лучший вариант, не зная больше о вашей архитектуре, но подклассы могут перехватывать события в родительском классе с помощью переопределения методов. Например, в классе ElementLabel:

public override void set(String key, object newValue) { 
    if (key.Equals("Value")) 
     set("Text", "New label text!"); 
    base.set(key, newValue); 
} 

Если вы хотите получить более общее решение, вы можете включить шаблон наблюдателя в вашем родительском классе; см. the wikipedia page

+0

Ну, это своего рода очевидный ответ. Я знал, что у меня пропало что-то действительно простое, но в то время я не мог его видеть. Конечно, переопределение родительского метода в дочернем классе, а затем вызов его от ребенка выполнял эту работу для меня (я делал это раньше для других методов, стыдно за меня). Спасибо! PS - Я проверю, что наблюдатель все равно, кажется интересным :) PS2 - я бы поднял ваш ответ, но не могу этого сделать из-за отсутствия репутации:/ – viper

0

Вы можете использовать для данных класс (или классы), который реализует INotifyPropertyChanged.

Затем вам нужно будет передать дочерние элементы управления ссылкам на свойство «master», которое вы использовали для управления состоянием. (Это было бы идеально использовано классом Controller.) (Я буду ссылаться на этот объект как на объект «главный объект».)

Каждый из дочерних элементов управления будет подписаться на событие PropertyChanged.

Затем, когда контроллер изменяет значение одного из свойств объекта основного объекта, он поднимет событие PropertyChanged, и каждый заинтересованный ребенок сможет ответить соответствующим образом.

Этот подход помогает отделить контроллер от представлений.

Последовательность:

  1. Перед созданием дочерних элементов управления, создать объект мастер свойства. Сохраните ссылку на это в Контроллере или Основной форме (если вы используете это как контроллер).
  2. Перейдите к каждому дочернему элементу управления, которому это необходимо, ссылка на объект свойства master.
  3. Каждый дочерний элемент управления должен подписаться на событие основного объекта объекта PropertyChanged.
  4. Напишите соответствующий обработчик для каждого ребенка. Он будет иметь доступ к ссылке на объект основного объекта, чтобы он мог видеть новые значения любых свойств.
  5. Когда свойство необходимо изменить, контроллер просто устанавливает свойство по своему желанию. Внедрение сеттера свойств должно привести к событию PropertyChanged и будет уведомлять все заинтересованные дочерние элементы управления, которые будут обновлять свой интерфейс в ответ.

[EDIT] Это на самом деле реализация шаблона наблюдателя, упомянутого выше Райаном.

+0

Спасибо за ваш ответ, но простое решение от @ Райан сделал для меня работу :) Я бы поднял ваш ответ, но не могу этого сделать из-за отсутствия репутации: / – viper

Смежные вопросы