ابحث عن العقدة التي تم النقر عليها ضمن قائمة السياق

StackOverflow https://stackoverflow.com/questions/2527

سؤال

كيف يمكنني معرفة أي عقدة في القائمة الشجرية تم تنشيط قائمة السياق؟على سبيل المثال، النقر بزر الماوس الأيمن على العقدة وتحديد خيار من القائمة.

لا أستطيع استخدام TreeViews SelectedNode الخاصية لأن العقدة تم النقر عليها بزر الماوس الأيمن فقط ولم يتم تحديدها.

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

المحلول

يمكنك إضافة حدث النقر بالماوس إلى TreeView، ثم تحديد العقدة الصحيحة باستخدام GetNodeAt بالنظر إلى إحداثيات الماوس التي يوفرها MouseEventArgs.

void treeView1MouseUp(object sender, MouseEventArgs e)
{
    if(e.Button == MouseButtons.Right)
    {
        // Select the clicked node
        treeView1.SelectedNode = treeView1.GetNodeAt(e.X, e.Y);

        if(treeView1.SelectedNode != null)
        {
            myContextMenuStrip.Show(treeView1, e.Location);
        }
    }
}

نصائح أخرى

هنا هو الحل الخاص بي.ضع هذا السطر في حدث NodeMouseClick الخاص بـ TreeView:

 ((TreeView)sender).SelectedNode = e.Node;

أجد أن سلوك اختيار سلوك Treeview القياسي لنظام Windows مزعج للغاية.على سبيل المثال، إذا كنت تستخدم Explorer وقمت بالنقر بزر الماوس الأيمن على العقدة ثم الضغط على "خصائص"، فسيتم تمييز العقدة ويظهر مربع حوار الخصائص الخاص بالعقدة التي نقرت عليها.ولكن عند العودة من مربع الحوار، تكون العقدة المميزة هي العقدة التي تم تحديدها/تمييزها مسبقًا قبل النقر بزر الماوس الأيمن.أجد أن هذا يسبب مشاكل في قابلية الاستخدام لأنني في حيرة من أمري بشأن ما إذا كنت قد تصرفت على العقدة الصحيحة.

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

إليك بعض التعليمات البرمجية التي تغير التحديد أثناء النقر بزر الماوس الأيمن:

  private void tree_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
  {
     // only need to change selected note during right-click - otherwise tree does
     // fine by itself
     if ( e.Button == MouseButtons.Right )
     {         
        Point pt = new Point( e.X, e.Y );
        tree.PointToClient( pt );

        TreeNode Node = tree.GetNodeAt( pt );
        if ( Node != null )
        {
           if ( Node.Bounds.Contains( pt ) )
           {
              tree.SelectedNode = Node;
              ResetContextMenu();
              contextMenuTree.Show( tree, pt );
           }
        }
     }
  }

إحياء هذا السؤال لأنني أجد أن هذا حل أفضل بكثير.انا استعمل ال NodeMouseClick الحدث بدلا من ذلك.

void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if( e.Button == MouseButtons.Right )
    {
        tree.SelectedNode = e.Node;
    }
}

على غرار إجابة ماركوس، كان هذا هو الحل الذي وجدته مناسبًا لي:

private void treeView_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        treeView.SelectedNode = treeView.GetNodeAt(e.Location);
    }
}

لا تحتاج إلى إظهار قائمة السياق بنفسك إذا قمت بتعيينها على كل عقدة على حدة كما يلي:

TreeNode node = new TreeNode();
node.ContextMenuStrip = contextMenu;

ثم داخل حدث فتح contextMenu، ستعكس خاصية TreeView.SelectedNode العقدة الصحيحة.

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

// Global Private Variable to hold right-clicked Node
private TreeNode _currentNode = new TreeNode();

// Set Global Variable to the Node that was right-clicked
private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
        _currentNode = e.Node;
}

// Do something when the Menu Item is clicked using the _currentNode
private void toolStripMenuItem_Clicked(object sender, EventArgs e)
{
    if (_currentNode != null)
        MessageBox.Show(_currentNode.Text);
}

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

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

هنا كيف أفعل ذلك.

private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
        e.Node.TreeView.SelectedNode = e.Node;
}

هناك خيار آخر يمكنك تشغيله وهو أن يكون لديك متغير عام يحتوي على العقدة المحددة.سوف تحتاج فقط إلى استخدام TreeNodeMouseClickEventArgs.

public void treeNode_Click(object sender, TreeNodeMouseClickEventArgs e)
{
    _globalVariable = e.Node;
}

الآن لديك حق الوصول إلى تلك العقدة وخصائصها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top