Форум: "Начинающим";
Текущий архив: 2007.04.15;
Скачать: [xml.tar.bz2];
ВнизВзаимодействие объекта и его UI представления — как организовать? Найти похожие ветки
← →
Kolan © (2007-03-24 20:34) [0]Здравствуйте,
Есть объект, допустим он состоит из одного поля типа string, и его UI представление — TEdit.
Как реализовать синхронизацию?
Те если вдруг пользователь изменил «Эдит», то должен изменится и объект.
А если изменился сам объект, то соответственно изменения должны отобразится на UI.
И ессно не должно быть зацикливания.
← →
RASkov (2007-03-24 21:48) [1]А что такое "объект"?
← →
Leonid Troyanovsky © (2007-03-24 22:35) [2]
> Kolan © (24.03.07 20:34)
> Есть объект, допустим он состоит из одного поля типа string,
> и его UI представление — TEdit.
> Как реализовать синхронизацию?
Если допустить не одно поле, а, скажем, TStringList, то смотри,
например, TDrawGrid, TListBox with lbVirtualOwnerDraw & etc.
--
Regards, LVT.
← →
Kolan © (2007-03-24 22:36) [3]«А что такое „объект“?»
Экземпляр класса вестимо :). Например:TSomeObject = clsaa
strict private
FField: string;
public
property Field: string read FField write FField;
end;
← →
Kolan © (2007-03-24 22:37) [4]«Если допустить не одно поле»
На самом деле полей много, и они разнотипные(string, Integer, TStrings…).
«TListBox with lbVirtualOwnerDraw „
Понял — посмотрю.
← →
Leonid Troyanovsky © (2007-03-24 22:51) [5]
> Kolan © (24.03.07 22:37) [4]
> «TListBox with lbVirtualOwnerDraw „
> Понял — посмотрю.
У EDIT нет виртуальной формы, т.е., видимо, нужды не возникало.
Т.е., смотреть, вообще-то, лучше б было на TStringList.OnChang*.
Принцип простой: вместо полей - свойства, побочные(видимые)
эффекты - в сеттерах.
--
Regards, LVT.
← →
Kolan © (2007-03-24 22:53) [6]Так, как данные брать понятно, а наоборот, куда смотреть?
function TCustomListBox.DoGetData(const Index: Integer): String;
begin
if Assigned(FOnData) then FOnData(Self, Index, Result);
end;
← →
Leonid Troyanovsky © (2007-03-24 22:55) [7]
> Kolan © (24.03.07 22:37) [4]
> На самом деле полей много, и они разнотипные(string, Integer,
> TStrings…).
Скажем, один TDrawGrid - лучше многих TEdit.
--
Regards, LVT.
← →
RASkov (2007-03-24 22:58) [8]
type
TMyObject = class
private
Edit: TEdit;
procedure SetStr(const Value: String);
function GetStr: String;
public
constructor Create(AEdit: TEdit);
procedure SetEdit(AEdit: TEdit);
property Str: String read GetStr write SetStr;
end;
........
constructor TMyObject.Create(AEdit: TEdit);
begin
inherited Create;
SetEdit(AEdit);
end;
procedure TMyObject.SetEdit(AEdit: TEdit);
begin
if not Assigned(AEdit) then raise Exception.Create("Больной едит");
Edit:=AEdit;
end;
function TMyObject.GetStr: String;
begin
Result:=Edit.Text;
end;
procedure TMyObject.SetStr(const Value: String);
begin
Edit.Text:=Value;
end;
← →
Leonid Troyanovsky © (2007-03-24 23:00) [9]
> Kolan © (24.03.07 22:53) [6]
> Так, как данные брать понятно, а наоборот, куда смотреть?
В сеттере д.б. что-то типа VisualPresentation.Invalidate
--
Regards, LVT.
← →
Kolan © (2007-03-24 23:10) [10]«[8] RASkov (24.03.07 22:58)»
И еще подписаться на событие OnChange, допустим, «Эдита» — вроде понял…
«Скажем, один TDrawGrid — лучше многих TEdit.»
Не, это не тот случай :)
«В сеттере д.б. что-то типа VisualPresentation.Invalidate»
Типо через сообщение?procedure TWinControl.Invalidate;
begin
Perform(CM_INVALIDATE, 0, 0);
end;
Я просто не понял что есть «сеттер»…
← →
Kolan © (2007-03-24 23:20) [11]Вывод сделал такой:
Нужен объект синхронизации, который будет знать и о «УИ», и об «объекте», и все обращения через этот синхронизатор. Так?
← →
Leonid Troyanovsky © (2007-03-24 23:36) [12]
> Kolan © (24.03.07 23:10) [10]
> Я просто не понял что есть «сеттер»…
Сеттер - метод, устанfвливающий значение свойства.
Понятие пришло к нам от плюсовых сишников, IMHO.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2007-03-24 23:40) [13]
> Kolan © (24.03.07 23:20) [11]
> Нужен объект синхронизации, который будет знать и о «УИ»,
> и об «объекте», и все обращения через этот синхронизатор.
В принципе, оно правильно. Сравни, например, с TDataSource.
Но, в жизни бывает и проще, т.е., без четкого разделения.
--
Regards, LVT.
← →
RASkov (2007-03-25 00:03) [14]> И еще подписаться на событие OnChange
А зачем?var T: TMyObject;
.....
procedure TForm.Button1Click(Sender: TObject);
begin
T.Str:="Stroka";
Edit2.Text:=Edit1.Text;
end;
procedure TForm.Button2Click(Sender: TObject);
begin
Edit1.Text:="NewStroka";
Edit2.Text:=T.Str;
end;
Т.е. меняешь хоть свойство Str, хоть сам текст едита...
Для числовых полей нужно немного переделать методы GetXXXX и SetXXXX....
Хотя это может и не то что нужно... судя по постам выше.
← →
Kolan © (2007-03-25 10:54) [15]«Т.е. меняешь хоть свойство Str, хоть сам текст едита…»
По идее УИ не знает об объекте, он знает только о синхронизаторе.
Интересно а как в ECO это сделано? Как там бизнес логика отображается на контролах?
← →
RASkov (2007-03-25 11:14) [16]> По идее УИ не знает об объекте, он знает только о синхронизаторе.
Что-то я не совсем понял, в моем примере Edit1(который на форме) тоже не "знает" о TMyObject. А синхронизатор... синхронизатором работает сам объект...
можно немного доработать и если нет ассоцированного Едита хранить строку в переменной(в поле)...
Но всеж наверное нужно что-нить типа TDataSource...
← →
default © (2007-03-25 11:53) [17]ну можно добавить один и тот же обработчик события для события изменения свойства Text у едита и у объекта
а в этом обработчике по Sender-у будет понятно от кого пришло событие-от едита или от объекта
и если от объкта менять свойство Text у едита и наоборот
рекурсии тут не будет, ибо делаем синхронизацию только когда свойства не равны
← →
default © (2007-03-25 12:52) [18]
Private obj As YourClass
"конструктор формы
Public Sub New()
InitializeComponent()
obj = New YourClass()
obj.Tag = TextBox3
TextBox3.Tag = obj
AddHandler obj.TextChanged, AddressOf SynhroTextChanged
AddHandler TextBox3.TextChanged, AddressOf SynhroTextChanged
End Sub
Private Sub SynhroTextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged
If TypeOf sender Is TextBox Then
Dim tb As TextBox = CType(sender, TextBox)
Dim o As YourClass = CType(tb.Tag, YourClass)
o.Text = tb.Text
ElseIf TypeOf sender Is YourClass Then
Dim o As YourClass = CType(sender, YourClass)
Dim tb As TextBox = CType(o.Tag, TextBox)
tb.Text = o.Text
End If
End Sub
"Это класс формы
End Class
Public Class YourClass
Private mvarText As String
Private mvarTag As Object
Public Property Text() As String
Get
Return mvarText
End Get
Set(ByVal value As String)
If mvarText <> value Then
mvarText = value
OnTextChanged(EventArgs.Empty)
End If
End Set
End Property
Public Property Tag() As Object
Get
Return mvarTag
End Get
Set(ByVal value As Object)
mvarTag = value
End Set
End Property
Protected Overridable Sub OnTextChanged(ByVal e As EventArgs)
RaiseEvent TextChanged(Me, e)
End Sub
Public Event TextChanged As EventHandler
End Class
это код на VB
но, неверно, можно разобраться
это просто как пример
← →
default © (2007-03-25 12:55) [19]на VB .NET вернее
← →
default © (2007-03-25 13:02) [20]ну можно добавить один и тот же обработчик события для события изменения свойства Text у едита и у объекта
а в этом обработчике по Sender-у будет понятно от кого пришло событие-от едита или от объекта
объект будет храниться в свойстве Tag у едита и наоборот
и если от объкта менять свойство Text у едита и наоборот
рекурсии тут не будет, ибо делаем синхронизацию только когда свойства не равны
здесь используется концепция, что у двух синхронизируемых объектов есть свойство Tag для хранения чего угодно
то есть тут как бы синхронизирующий обработчик события изменения текста это как бы внешний код выполняющий синхронизацию(то есть синхронизирующие объъекты как бы и понятия не имеют что их свойство Text синхронизируются:))
можно использовать и другую концепцию
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.04.15;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.046 c