2012-08-27 10 views
8

ठीक है मुझे कुछ वास्तव में मुश्किल मिल गया है ... मैं एक चाइल्ड नोड के लिए शीर्षलेख/उपयोग करना चाहता हूं। मुझे लगता है कि विचार उचित है क्योंकि यह उपन्यास में हेडर रखने के लिए आश्चर्यजनक लगेगा ताकि बालनोड को तालिका में निर्दिष्ट किया जा सके। क्या ऐसी सुविधा है जो VST है या यह संभव नहीं है?क्या मास्टर विवरण ग्रिड व्यू के लिए वर्चुअलस्ट्रिंगट्री का उपयोग करना संभव है?

आपकी मदद के लिए धन्यवाद।

+1

पिछली बार मैंने इस तरह के एक विचार की जांच की, मैं इसके लिए आपके VirtualTreeView का उपयोग कर छोड़ समाप्त हो गया है, और डेवलपर एक्सप्रेस, जो में बनाया गया इस तरह की क्षमता है से एक्सप्रेस क्वांटम ग्रिड की तरह कुछ का इस्तेमाल किया। यह प्रकार है उस बिंदु पर एक पेड़-दृश्य की तुलना में एक ग्रिड (घोंसले ग्रिड) के अंदर एक ग्रिड का अधिक। –

+1

@Warren, ग्रिड के अंदर * ग्रिड के बारे में आपका बिंदु * मुझे एक पागल विचार लाया, वर्चुअल ट्री व्यू के अंदर एक नेस्टेड वर्चुअल ट्री व्यू बनाएं और पतन पर इसकी दृश्यता को नियंत्रित करें और नोड घटनाओं का विस्तार करें। इसे अनुकरण करने से लागू करना निश्चित रूप से आसान होगा। – TLama

+0

तो असंभव नहीं है? –

उत्तर

14

1. क्या मास्टर/विस्तार ग्रिड व्यू के लिए VirtualTreeView का उपयोग करने का कोई तरीका है?

नहीं, इस समय ऐसी कोई सुविधा उपलब्ध नहीं है और आईएमएचओ नहीं होगा, क्योंकि इसमें मौजूदा कोड में बहुत बड़ा हस्तक्षेप शामिल होगा।

2. बच्चे नोड विवरण ग्रिड व्यू के लिए पूरी तरह कार्यात्मक शीर्षलेख कैसे बनाएं?

कुछ तरीकों को ध्यान में रखते हुए, बाल नोड्स के लिए हेडर लुक और व्यवहार को अनुकरण कैसे करें, मुझे विस्तृत ग्रिड व्यू के लिए नेस्टेड पेड़ दृश्यों का उपयोग करने में उपयोगी पाया गया है। यह आपको अपने विस्तार डेटा के लिए अलगाव लाता है और आपको पूरे सिमुलेशन को नेस्टेड पेड़ दृश्य की स्थिति को एक बच्चे नोड के आयत में कम करने की अनुमति देता है।

2.1। स्टार्टअप परियोजना

निम्नलिखित परियोजना में मैं दिखाने के लिए कि कैसे जटिल एक बच्चे नोड के अंदर एक नियंत्रण की स्थिति की तरह इस तरह के एक आसान काम को लागू (मूल VirtualTree कोड को शामिल किए बिना) हो सकता है हो सकता है कोशिश कर रहा हूँ। इसे स्टार्टअप प्रोजेक्ट के रूप में लें, अंतिम समाधान के रूप में नहीं।

2.2। ज्ञात मामले & सीमाएं:

  • इस परियोजना लिखा गया था और रूट नोड प्रति केवल एक ही बच्चा उपयोग करने के लिए परीक्षण किया, तो एक व्यवहार है जब आप इस सीमा से अधिक के साथ तो हैरान न हों, क्योंकि यह नहीं बनाया गया था और न ही और भी
  • के लिए परीक्षण किया है जब एक मुख्य पेड़ की एक डबल क्लिक करें स्तंभ का आकार बदलने स्तंभ का आकार बदलने, नेस्टेड पेड़ विचारों लाइनों के साथ आहरित जब कैनवास ScrollDC समारोह
  • द्वारा स्क्रॉल किया जा रहा है मैं बदले बिना VirtualTree कोड रखने के लिए कर रहे हैं 'एनिमेट स्क्रॉल बार अपडेट करने के लिए विधि को ओवरराइड किया है। जब भी स्क्रॉलबार को अद्यतन करने की आवश्यकता होती है तो इसका उपयोग घोंसला वाले पेड़ दृश्यों को अद्यतन करने के लिए किया जाता है
  • वर्तमान OnExpanded कार्यान्वयन सीमा से पहले घटना को सक्रिय करता है और स्क्रॉल स्थिति तय की जाती है, जो कोड को अधिक जटिल बनाता है और बड़ी कमजोरी के साथ - एक की सीमाएं के बाद पेड़ दिखाया गया है विस्तार ट्री व्यू अपडेट किया जाता है, कभी कभी दिखाई

2,3 हो सकता है क्या। परियोजना कोड

डेल्फी 7 में उपयोग के संबंध में डेल्फी 200 9 में लिखा और परीक्षण किया गया था।

Unit1.pas

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, VirtualTrees; 

type 
    TVTScrollBarsUpdateEvent = procedure(Sender: TBaseVirtualTree; DoRepaint: Boolean) of object; 
    TVirtualStringTree = class(VirtualTrees.TVirtualStringTree) 
    private 
    FOnUpdateScrollBars: TVTScrollBarsUpdateEvent; 
    public 
    procedure UpdateScrollBars(DoRepaint: Boolean); override; 
    published 
    property OnUpdateScrollBars: TVTScrollBarsUpdateEvent read FOnUpdateScrollBars write FOnUpdateScrollBars; 
    end; 

type 
    PNodeSubTree = ^TNodeSubTree; 
    TNodeSubTree = class 
    FChildTree: TVirtualStringTree; 
    end; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    VirtualStringTree1: TVirtualStringTree; 
    procedure FormCreate(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    procedure VirtualStringTree1AfterAutoFitColumns(Sender: TVTHeader); 
    procedure VirtualStringTree1BeforeDrawTreeLine(Sender: TBaseVirtualTree; 
     Node: PVirtualNode; Level: Integer; var PosX: Integer); 
    procedure VirtualStringTree1Collapsed(Sender: TBaseVirtualTree; 
     Node: PVirtualNode); 
    procedure VirtualStringTree1ColumnResize(Sender: TVTHeader; 
     Column: TColumnIndex); 
    procedure VirtualStringTree1Expanded(Sender: TBaseVirtualTree; 
     Node: PVirtualNode); 
    procedure VirtualStringTree1FocusChanging(Sender: TBaseVirtualTree; OldNode, 
     NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex; 
     var Allowed: Boolean); 
    procedure VirtualStringTree1FreeNode(Sender: TBaseVirtualTree; 
     Node: PVirtualNode); 
    procedure VirtualStringTree1MeasureItem(Sender: TBaseVirtualTree; 
     TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer); 
    private 
    procedure InvalidateSubTrees(Tree: TBaseVirtualTree); 
    procedure ResizeSubTrees(Tree: TBaseVirtualTree); 
    procedure UpdateSubTreeBounds(Tree: TBaseVirtualTree; Node: PVirtualNode); 
    procedure OnUpdateScrollBars(Sender: TBaseVirtualTree; DoRepaint: Boolean); 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

{ TVirtualStringTree } 

procedure TVirtualStringTree.UpdateScrollBars(DoRepaint: Boolean); 
begin 
    inherited; 
    if HandleAllocated and Assigned(FOnUpdateScrollBars) then 
    FOnUpdateScrollBars(Self, DoRepaint); 
end; 

{ TForm1 } 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    ReportMemoryLeaksOnShutdown := True; 
    VirtualStringTree1.NodeDataSize := SizeOf(TNodeSubTree); 
    VirtualStringTree1.OnUpdateScrollBars := OnUpdateScrollBars; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    Data: PNodeSubTree; 
    Node: PVirtualNode; 
begin 
    Node := VirtualStringTree1.AddChild(nil); 
    Node := VirtualStringTree1.AddChild(Node); 
    VirtualStringTree1.InitNode(Node); 
    Data := VirtualStringTree1.GetNodeData(Node); 
    Data^ := TNodeSubTree.Create; 
    Data^.FChildTree := TVirtualStringTree.Create(nil); 
    with Data.FChildTree do 
    begin 
    Visible := False; 
    Parent := VirtualStringTree1; 
    Height := 150; 
    DefaultNodeHeight := 21; 
    Header.AutoSizeIndex := 0; 
    Header.Font.Charset := DEFAULT_CHARSET; 
    Header.Font.Color := clWindowText; 
    Header.Font.Height := -11; 
    Header.Font.Name := 'Tahoma'; 
    Header.Font.Style := []; 
    Header.Height := 21; 
    Header.Options := [hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible]; 
    TabStop := False; 
    with Header.Columns.Add do 
    begin 
     Width := 100; 
     Text := 'Header item 1'; 
    end; 
    with Header.Columns.Add do 
    begin 
     Width := 100; 
     Text := 'Header item 2'; 
    end; 
    end; 
end; 

procedure TForm1.VirtualStringTree1AfterAutoFitColumns(Sender: TVTHeader); 
begin 
    InvalidateSubTrees(Sender.Treeview); 
end; 

procedure TForm1.VirtualStringTree1BeforeDrawTreeLine(Sender: TBaseVirtualTree; 
    Node: PVirtualNode; Level: Integer; var PosX: Integer); 
begin 
    if Level = 1 then 
    PosX := 0; 
end; 

procedure TForm1.VirtualStringTree1Collapsed(Sender: TBaseVirtualTree; 
    Node: PVirtualNode); 
var 
    Data: PNodeSubTree; 
begin 
    Data := VirtualStringTree1.GetNodeData(Node.FirstChild); 
    if Assigned(Data^) and Assigned(Data^.FChildTree) then 
    Data^.FChildTree.Visible := False; 
end; 

procedure TForm1.VirtualStringTree1ColumnResize(Sender: TVTHeader; 
    Column: TColumnIndex); 
begin 
    ResizeSubTrees(Sender.Treeview); 
end; 

procedure TForm1.VirtualStringTree1Expanded(Sender: TBaseVirtualTree; 
    Node: PVirtualNode); 
var 
    Data: PNodeSubTree; 
begin 
    Data := VirtualStringTree1.GetNodeData(Node.FirstChild); 
    if Assigned(Data^) and Assigned(Data^.FChildTree) then 
    Data^.FChildTree.Visible := True; 
end; 

procedure TForm1.VirtualStringTree1FocusChanging(Sender: TBaseVirtualTree; 
    OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex; 
    var Allowed: Boolean); 
begin 
    if Sender.GetNodeLevel(NewNode) = 1 then 
    begin 
    Allowed := False; 
    if Sender.AbsoluteIndex(OldNode) > Sender.AbsoluteIndex(NewNode) then 
     Sender.FocusedNode := Sender.GetPreviousSibling(OldNode) 
    else 
    if OldNode <> Sender.GetLastChild(nil) then 
     Sender.FocusedNode := Sender.GetNextSibling(OldNode) 
    else 
     Sender.FocusedNode := OldNode; 
    end; 
end; 

procedure TForm1.VirtualStringTree1FreeNode(Sender: TBaseVirtualTree; 
    Node: PVirtualNode); 
var 
    Data: PNodeSubTree; 
begin 
    Data := VirtualStringTree1.GetNodeData(Node); 
    if Assigned(Data^) then 
    begin 
    if Assigned(Data^.FChildTree) then 
     Data^.FChildTree.Free; 
    Data^.Free; 
    end; 
end; 

procedure TForm1.VirtualStringTree1MeasureItem(Sender: TBaseVirtualTree; 
    TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer); 
var 
    Data: PNodeSubTree; 
begin 
    if VirtualStringTree1.GetNodeLevel(Node) = 1 then 
    begin 
    Data := VirtualStringTree1.GetNodeData(Node); 
    if Assigned(Data^) and Assigned(Data^.FChildTree) then 
     NodeHeight := Data^.FChildTree.Height + 8; 
    end; 
end; 

procedure TForm1.InvalidateSubTrees(Tree: TBaseVirtualTree); 
var 
    Data: PNodeSubTree; 
    Node: PVirtualNode; 
begin 
    Node := Tree.GetFirst; 
    while Assigned(Node) do 
    begin 
    if Tree.HasChildren[Node] then 
    begin 
     Data := Tree.GetNodeData(Node.FirstChild); 
     if Assigned(Data^) and Assigned(Data^.FChildTree) then 
     begin 
     Data^.FChildTree.Header.Invalidate(nil); 
     Data^.FChildTree.Invalidate; 
     end; 
    end; 
    Node := Tree.GetNextSibling(Node); 
    end; 
end; 

procedure TForm1.ResizeSubTrees(Tree: TBaseVirtualTree); 
var 
    Node: PVirtualNode; 
begin 
    Node := Tree.GetFirst; 
    while Assigned(Node) do 
    begin 
    if Tree.HasChildren[Node] then 
     UpdateSubTreeBounds(Tree, Node.FirstChild); 
    Node := Tree.GetNextSibling(Node); 
    end; 
end; 

procedure TForm1.UpdateSubTreeBounds(Tree: TBaseVirtualTree; Node: PVirtualNode); 
var 
    R: TRect; 
    Data: PNodeSubTree; 
begin 
    if Assigned(Node) then 
    begin 
    Data := Tree.GetNodeData(Node); 
    if Assigned(Data^) and Assigned(Data^.FChildTree) and 
     Data^.FChildTree.Visible then 
    begin 
     R := Tree.GetDisplayRect(Node, -1, False, True); 
     R.Left := R.Left + (Tree as TVirtualStringTree).Indent; 
     R.Top := R.Top + 4; 
     R.Right := R.Right - 8; 
     R.Bottom := R.Bottom - 4; 
     Data^.FChildTree.BoundsRect := R; 
    end; 
    end; 
end; 

procedure TForm1.OnUpdateScrollBars(Sender: TBaseVirtualTree; DoRepaint: Boolean); 
begin 
    ResizeSubTrees(Sender); 
end; 

end. 

Unit1.dfm

object Form1: TForm1 
    Left = 0 
    Top = 0 
    Caption = 'Form1' 
    ClientHeight = 282 
    ClientWidth = 468 
    Color = clBtnFace 
    Font.Charset = DEFAULT_CHARSET 
    Font.Color = clWindowText 
    Font.Height = -11 
    Font.Name = 'Tahoma' 
    Font.Style = [] 
    OldCreateOrder = False 
    OnCreate = FormCreate 
    DesignSize = (
    468 
    282) 
    PixelsPerInch = 96 
    TextHeight = 13 
    object VirtualStringTree1: TVirtualStringTree 
    Left = 8 
    Top = 8 
    Width = 371 
    Height = 266 
    Anchors = [akLeft, akTop, akRight, akBottom] 
    Header.AutoSizeIndex = 0 
    Header.Font.Charset = DEFAULT_CHARSET 
    Header.Font.Color = clWindowText 
    Header.Font.Height = -11 
    Header.Font.Name = 'Tahoma' 
    Header.Font.Style = [] 
    Header.Height = 21 
    Header.Options = [hoColumnResize, hoDblClickResize, hoDrag, hoShowSortGlyphs, hoVisible] 
    TabOrder = 0 
    TreeOptions.MiscOptions = [toVariableNodeHeight] 
    OnAfterAutoFitColumns = VirtualStringTree1AfterAutoFitColumns 
    OnBeforeDrawTreeLine = VirtualStringTree1BeforeDrawTreeLine 
    OnCollapsed = VirtualStringTree1Collapsed 
    OnColumnResize = VirtualStringTree1ColumnResize 
    OnExpanded = VirtualStringTree1Expanded 
    OnFocusChanging = VirtualStringTree1FocusChanging 
    OnFreeNode = VirtualStringTree1FreeNode 
    OnMeasureItem = VirtualStringTree1MeasureItem 
    ExplicitWidth = 581 
    ExplicitHeight = 326 
    Columns = < 
     item 
     Position = 0 
     Width = 75 
     WideText = 'Column 1' 
     end 
     item 
     Position = 1 
     Width = 75 
     WideText = 'Column 2' 
     end 
     item 
     Position = 2 
     Width = 75 
     WideText = 'Column 3' 
     end> 
    end 
    object Button1: TButton 
    Left = 385 
    Top = 8 
    Width = 75 
    Height = 25 
    Anchors = [akTop, akRight] 
    Caption = 'Button1' 
    TabOrder = 1 
    OnClick = Button1Click 
    ExplicitLeft = 595 
    end 
end 

2,4: एक अगली कोड follow this link की टिप्पणी की संस्करण के लिए। स्क्रीनशॉट

enter image description here

+1

यह मेरे जीवन में अब तक का सबसे प्रभावशाली कोड है! इच्छा है कि मैं आपको इसके लिए अधिक प्रतिनिधि अंक दे सकता हूं! –

+0

toVariableNodeHeight TreeOptions.MiscOptions में अनुपलब्ध है, इस नमूना प्रोजेक्ट के लिए इसकी आवश्यकता है, अन्यथा OnMeasureItem को नहीं कहा जाता है। –

+0

@ जोचिम, संकेत के लिए धन्यवाद! मुझे पूरा यकीन है कि मैंने प्रोजेक्ट की प्रतिलिपि बनाई थी क्योंकि जब मैंने स्क्रीनशॉट लिया था, तो यह वीटी का सिर्फ पुराना संस्करण हो सकता है जिसने 'MiscMeasureItem 'ईवेंट को' MiscOptions 'सेट में शामिल किए बिना इस विकल्प के बिना भी निकाल दिया। दुर्भाग्यवश मैंने इस बात का जिक्र नहीं किया कि मैंने उस संस्करण का उपयोग उस समय सत्यापित करने के लिए किया था। – TLama

संबंधित मुद्दे