سؤال

هذه نسخة محدثة من سؤال نشر سابقا، كان العنوان السابق اختيار العقدة حسب الفهرس في Delphi's Treeview الظاهري.]

بعد الجزء الأفضل من اليوم، أعتقد أنني حصلت على مكون TreeView الظاهري (قوية ولكن معقدة) تعمل في بيانات طاولة بسيطة على الأزياء.

الآن، أحاول ببساطة اختيار 1،512 (على سبيل المثال) لعقد المستوى الأعلى. لا أستطيع أن أرى أي طريقة للقيام بذلك بخلاف الحصول على أول عقدة المستوى الأعلى ثم استدعاء GetNextsibling 1،511 في حلقة.

هذا يبدو مشاركا دون داع. هل هناك طريقة أبسط؟

تحديث

نظرا لأن تهيئة العقد في أشجارتي تتطلب الوصول إلى قاعدة البيانات، فإن تهيئة جميع العقد عند بدء التشغيل غير ممكن. عندما يبدأ المستخدم بالشكل بدون سجل محدد بالفعل، هذا جيد. كما يتم تمرير المستخدم في جميع أنحاء الشجرة، يتم ملء عدد كاف من العقد لعرض النافذة الحالية في الشجرة والأداء على ما يرام.

عندما يبدأ المستخدم في النموذج في وضع الحوار مع سجل قاعدة بيانات محددة بالفعل، يجب علي دفع الشجرة إلى تلك العقدة قبل أن يرى المستخدم النموذج. هذه مشكلة لأنه، إذا كان السجل في نهاية الشجرة، فقد يستغرق الأمر عشر ثوان وأنا أمشي الشجرة من العقدة الأولى. في كل مرة أستطيع الحصول عليها ()، تتم تهيئة العقدة، على الرغم من أن الغالبية العظمى من تلك العقد لا يتم عرضها للمستخدم. أفضل أن أؤجل تهيئة تلك العقد إلى النقطة التي يصبحونها مرئية للمستخدم.

أعلم أنه يجب أن يكون هناك طريقة أفضل، لأنه إذا قمت بفتح الشجرة دون وجود سجل محدد واستخدم شريط التمرير العمودي للتحرك، في عملية واحدة، إلى منتصف الشجرة، يتم عرض العقد الصحيحة دون الحاجة إلى تهيئة العقد التي تخطيتها.

هذا هو التأثير الذي أود تحقيقه عند فتح الشجرة بسجل محدد. وأنا أعلم أن مؤشر العقدة أريد أن أذهب إليه، ولكن إذا لم أتمكن من الوصول إلى هناك عن طريق الفهرس، فيمكنني القيام بعمل ثنائي على الشجرة على افتراض أنني أستطيع القفز بعض العقد إلى الوراء وإلى الأمام (مماثلة للتمرير مباشرة إلى التمرير مباشرة إلى منتصف الشجرة).

بدلا من ذلك، ربما هناك بعض الإعداد الحكومي الذي يمكنني إجراؤه على عرض الشجرة الذي سيغادر العقد الوسيطة غير متجانسة بأقلتي اجتاز الشبكة. لقد حاولت تحديث / نهاية التحديث وهذا لا يبدو أن تفعل الخدعة.

هل كانت مفيدة؟

المحلول

للحصول على أخوة العقدة دون تهيئة ذلك، فقط استخدم NextSibling مؤشر (انظر إعلان TVirtualNode).

نصائح أخرى

يتم تنظيم التحكم في الشجرة تماما مثل الأشجار الكلاسيكية التي ستتعلمها في فئة علم الكمبيوتر. الطريقة الوحيدة للوصول من جذر الشجرة إلى الطفل 1512 هي المشي الروابط واحدا تلو الآخر. سواء كنت تفعل ذلك بنفسك أو تستخدم طريقة للتحكم في الشجرة، فلا يزال يتعين القيام به بهذه الطريقة. لا أرى أي شيء ينص على التحكم نفسه، حتى تتمكن من استخدام هذه الوظيفة:

function GetNthNextSibling(Node: PVirtualNode; N: Cardinal;
  Tree: TBaseVirtualTree = nil): PVirtualNode;
begin
  if not Assigned(Tree) then
    Tree := TreeFromNode(Node);
  Result := Node;
  while Assigned(Result) and (N > 0) do begin
    Dec(N);
    Result := Tree.GetNextSibling(Result);
  end;
end;

إذا وجدت نفسك تفعل ذلك في كثير من الأحيان، فقد ترغب في جعل نفسك فهرس. قد يكون بسيطة مثل صنع مجموعة من PVirtualNode المؤشرات وتخزين جميع قيم المستوى الأعلى فيه، بحيث يمكنك فقط قراءة القيمة 1512 للخروج منها. لا حاجة عنصر التحكم في الأشجار لهيكل البيانات نفسه، لذلك لا يحافظ على واحد.

قد تقوم أيضا بإعادة النظر في ما إذا كان أنت تحتاج إلى بنية البيانات من هذا القبيل. هل أنت هل حقا بحاجة إلى الوصول إلى العقد عن طريق الفهرس من هذا القبيل؟ أو يمكن أن تحافظ بدلا من ذلك PVirtualNode مؤشر، لذلك موقفه بالنسبة لبقية العقد في الشجرة لم يعد يهم (يعني أنه يمكنك، على سبيل المثال، فرزها دون فقدان إشارة إلى العقدة التي تريدها)؟

تكتب في التحديث الخاص بك:

أعلم أنه يجب أن يكون هناك طريقة أفضل، لأنه إذا قمت بفتح الشجرة دون وجود سجل محدد واستخدم شريط التمرير العمودي للتحرك، في عملية واحدة، إلى منتصف الشجرة، يتم عرض العقد الصحيحة دون الحاجة إلى تهيئة العقد التي تخطيتها.

هناك فرق هنا، لأن التمرير العمودي يغير تنسيق Y المنطقي الذي يتم عرضه في موضع العميل 0. يحسب عنصر التحكم الإزاحة من موضع التمرير ومدركة التمرير، ثم يحسب العقدة المرئية في الجزء العلوي من عنصر التحكم. يتم تهيئة العقد مرة أخرى فقط عندما تكون المنطقة التي تم تمريرها إلى عرض لاحتياجات.

إذا كان لديك تنسيق ذ العقدة، يمكنك الحصول على مؤشر العقدة عن طريق الاتصال

function TBaseVirtualTree.GetNodeAt(X, Y: Integer; Relative: Boolean;
  var NodeTop: Integer): PVirtualNode;

الإحداثي Y للعقدة هو مجموع مرتفعات جميع العقد السابقة المرئية. على افتراض أنك لم تنهار العقد (لذلك إما أنها قائمة مسطحة من السجلات، أو يتم توسيع جميع العقد مع العقد الطفولة) ولكلها جميعها الارتفاع الافتراضي هذا سهل. يجب أن يكون هذا الرمز نقطة انطلاق جيدة:

procedure TForm1.SelectTreeNode(AIndex: integer; ACenterNodeInTree: boolean);
var
  Y, Dummy: integer;
  Node: PVirtualNode;
begin
  Y := Round((AIndex + 0.5) * VirtualStringTree1.DefaultNodeHeight);
  Node := VirtualStringTree1.GetNodeAt(0, Y, False, Dummy);
  if Node <> nil then begin
    Assert(Node.Index = AIndex);
    VirtualStringTree1.ScrollIntoView(Node, ACenterNodeInTree);
    VirtualStringTree1.Selected[Node] := True;
    VirtualStringTree1.FocusedNode := Node;
  end;
end;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top