用TStrings做组件的属性,无法进入设置过程,应该怎么处理? ( 积分: 30 )

  • 主题发起人 主题发起人 维扬一少
  • 开始时间 开始时间

维扬一少

Unregistered / Unconfirmed
GUEST, unregistred user!
大家有没有试过用TStrings做组件的属性? 我有个组件中要用到
property Text: TStrings read FStrings write SetStrings
写法如上, 不过我怎么改Text属性都进不了setStrings过程,怎么办?
 
大家有没有试过用TStrings做组件的属性? 我有个组件中要用到
property Text: TStrings read FStrings write SetStrings
写法如上, 不过我怎么改Text属性都进不了setStrings过程,怎么办?
 
//给你我的控件这部分代码
//http://www.delphibbs.com/keylife/iblog_show.asp?xid=15051

private
FListFields:TStrings;
......
procedure SetListFields(Value:Tstrings);
......

public
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
......

published
property ListFields:TStrings read FListFields write SetListFields;
......

constructor ***.Create(AOwner:TComponent);
begin
FListFields := TStringList.Create; //这里是TStringList不是TStrings而且一定要这行
......

destructor ***.Destroy;
begin
FListFields.Free;
......

procedure ***.SetListFields(Value:Tstrings);
begin
FListFields.Assign(Value);
......

//在控件的ListFields属性会出现一个按钮,请加分!
 
除了要提供SetStrings方法外还要设置TStrings.OnChange实践. 对这个strings所做的修改主要是通过OnChange来获得的
 
FListFields := TStringList.Create;

FListFields := TMemoStrings.Create;
 
控件的属性,不用OnChange,以我的例子,任何时候只要修改了属性,自会执行SetListFields,我上面贴的例子是完整的,照搬不误应该没问题
 
必须得有个对象
 
kinneng,你的方法不行, 我一开始就是用的这样的方法,不能触发的! 我一开始以为当然可以触发的, 可就是不行
 
firstboy, 我研究了memo,listbox的代码,它们都对自己的他们都为自己的TStrings属性重新继承出一个新类, 可是这个类我没法直接用,有什么办法能直接引用的?
 
TStrings 是个抽象类,要用它的实现类 TStringsList;

如:
var Items :TStrings;
...
Items := TStringsList.Create;
....
 
to QSmile
我明白, 你试试你就知道了!!!
 
1先来看一下Vcl中的TStrings

TStrings = class(TPersistent)
private
FDefined: TStringsDefined;
FDelimiter: Char;
FQuoteChar: Char;
FUpdateCount: Integer;
FAdapter: IStringsAdapter;
function GetCommaText: string;
function GetDelimitedText: string;
function GetName(Index: Integer): string;
function GetValue(const Name: string): string;
procedure ReadData(Reader: TReader);
procedure SetCommaText(const Value: string);
procedure SetDelimitedText(const Value: string);
procedure SetStringsAdapter(const Value: IStringsAdapter);
procedure SetValue(const Name, Value: string);
procedure WriteData(Writer: TWriter);
function GetDelimiter: Char;
procedure SetDelimiter(const Value: Char);
function GetQuoteChar: Char;
procedure SetQuoteChar(const Value: Char);
protected
procedure DefineProperties(Filer: TFiler); override;
procedure Error(const Msg: string; Data: Integer); overload;
procedure Error(Msg: PResStringRec; Data: Integer); overload;
function ExtractName(const S: string): string;
function Get(Index: Integer): string; virtual; abstract;
function GetCapacity: Integer; virtual;
function GetCount: Integer; virtual; abstract;
function GetObject(Index: Integer): TObject; virtual;
function GetTextStr: string; virtual;
procedure Put(Index: Integer; const S: string); virtual;
procedure PutObject(Index: Integer; AObject: TObject); virtual;
procedure SetCapacity(NewCapacity: Integer); virtual;
procedure SetTextStr(const Value: string); virtual;
procedure SetUpdateState(Updating: Boolean); virtual;
property UpdateCount: Integer read FUpdateCount;
function CompareStrings(const S1, S2: string): Integer; virtual;
public
destructor Destroy; override;
function Add(const S: string): Integer; virtual;
function AddObject(const S: string; AObject: TObject): Integer; virtual;
procedure Append(const S: string);
procedure AddStrings(Strings: TStrings); virtual;
procedure Assign(Source: TPersistent); override;
procedure BeginUpdate;
procedure Clear; virtual; abstract;
procedure Delete(Index: Integer); virtual; abstract;
procedure EndUpdate;
function Equals(Strings: TStrings): Boolean;
procedure Exchange(Index1, Index2: Integer); virtual;
function GetText: PChar; virtual;
function IndexOf(const S: string): Integer; virtual;
function IndexOfName(const Name: string): Integer; virtual;
function IndexOfObject(AObject: TObject): Integer; virtual;
procedure Insert(Index: Integer; const S: string); virtual; abstract;
procedure InsertObject(Index: Integer; const S: string;
AObject: TObject); virtual;
procedure LoadFromFile(const FileName: string); virtual;
procedure LoadFromStream(Stream: TStream); virtual;
procedure Move(CurIndex, NewIndex: Integer); virtual;
procedure SaveToFile(const FileName: string); virtual;
procedure SaveToStream(Stream: TStream); virtual;
procedure SetText(Text: PChar); virtual;
property Capacity: Integer read GetCapacity write SetCapacity;
property CommaText: string read GetCommaText write SetCommaText;
property Count: Integer read GetCount;
property Delimiter: Char read GetDelimiter write SetDelimiter;
property DelimitedText: string read GetDelimitedText write SetDelimitedText;
property Names[Index: Integer]: string read GetName;
property Objects[Index: Integer]: TObject read GetObject write PutObject;
property QuoteChar: Char read GetQuoteChar write SetQuoteChar;
property Values[const Name: string]: string read GetValue write SetValue;
property Strings[Index: Integer]: string read Get write Put; default;
property Text: string read GetTextStr write SetTextStr;
property StringsAdapter: IStringsAdapter read FAdapter write SetStringsAdapter;
end;

在 TStrings中大多数public,protected中的函数都是virtual的,而且一下几个是virtual; abstract;的
所以你必须在子类中覆盖
function Get(Index: Integer): string; virtual; abstract;
procedure Clear; virtual; abstract;
procedure Delete(Index: Integer); virtual; abstract;
procedure Insert(Index: Integer; const S: string); virtual; abstract;

而在TMemoStrings中覆盖了这些函数 不同的是 TMemoStrings 有 Memo: TCustomMemo;
TMemoStrings = class(TStrings)
private
Memo: TCustomMemo;
protected
function Get(Index: Integer): string; override;
function GetCount: Integer; override;
function GetTextStr: string; override;
procedure Put(Index: Integer; const S: string); override;
procedure SetTextStr(const Value: string); override;
procedure SetUpdateState(Updating: Boolean); override;
public
procedure Clear; override;
procedure Delete(Index: Integer); override;
procedure Insert(Index: Integer; const S: string); override;
end;

这个 Memo: TCustomMemo 有什麽用处,可以和组件进行交互,请看
procedure TMemoStrings.SetTextStr(const Value: string);
var
NewText: string;
begin
NewText := AdjustLineBreaks(Value);
if (Length(NewText) <> Memo.GetTextLen) or (NewText <> Memo.Text) then
begin
if SendMessage(Memo.Handle, WM_SETTEXT, 0, Longint(NewText)) = 0 then
raise EInvalidOperation.Create(SInvalidMemoSize);
Memo.Perform(CM_TEXTCHANGED, 0, 0);
end;
end;

SetTextStr中没有使用inherited 所以数据 是通过 SendMessage 存入的,没有Memo是无法存取的


procedure TMemoStrings.Insert(Index: Integer; const S: string);
var
SelStart, LineLen: Integer;
Line: string;
begin
if Index >= 0 then
begin
SelStart := SendMessage(Memo.Handle, EM_LINEINDEX, Index, 0);
if SelStart >= 0 then Line := S + #13#10 else
begin
SelStart := SendMessage(Memo.Handle, EM_LINEINDEX, Index - 1, 0);
if SelStart < 0 then Exit;
LineLen := SendMessage(Memo.Handle, EM_LINELENGTH, SelStart, 0);
if LineLen = 0 then Exit;
Inc(SelStart, LineLen);
Line := #13#10 + s;
end;
SendMessage(Memo.Handle, EM_SETSEL, SelStart, SelStart);
SendMessage(Memo.Handle, EM_REPLACESEL, 0, Longint(PChar(Line)));
end;
end;

所以每次Insert ,Memo组件都会跳到正确的行处,

再看TCustomMemo.Create

constructor TCustomMemo.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Width := 185;
Height := 89;
AutoSize := False;
FWordWrap := True;
FWantReturns := True;
FLines := TMemoStrings.Create;
{* 注意这里}
TMemoStrings(FLines).Memo := Self;
end;


所以。如果你的组件也有这些与界面的交互作用 你必须写一个自己的TMemoStrings
如果你的组件没有与界面的交互作用 你用TStringList就可以了
 
很抱歉各位, 我刚刚又在delphi环境里面试了一下(之前都是用TdxRTTIInspector试的),一切正常,并没有出现不能进入设置过程的问题, 这么看来是TdxRTTIInspector的bug了!
有人用过TdxRTTIInspector吗? 这样的问题在TdxRTTIInspector里面是怎么解决的?
 
必须创建实际的对象,只有个变量是不行的
 
我试过是可以的,
还有你的控件是从什么控件继承来的,

是不是你父控件本身就有 Text 这个属性?
 
唉, 全是第三方组件的问题,害得我自己没问题在找问题, 得了, 散分:)
 
多人接受答案了。
 
后退
顶部