PDA

View Full Version : انتخاب تمامی فرزندان یک نود در tree view



Sal_64
جمعه 12 مهر 1387, 14:26 عصر
سلام
تو بخش جستجو کردم یک تاپیک دیدم که اونم به زبون وی بی بود !
اما طولانی بود

چطور در یک tree view با تیک زدن چک باکس یک نود تمامی فرزندان اون رو تا آخرین عمق (اینجا حداکثر 4 تا) انتخاب کرد

این کد رو چطور تغییر بدم تا به جواب برسم



if (treeView1.Nodes[0].Checked == true)
foreach (TreeNode nod in treeView1.--------)

treeView1.Nodes[0].--------.Checked = true;با تشکر

SMRAH1
جمعه 12 مهر 1387, 15:22 عصر
اگر اسم کنترل TreeView شما treeView1 باشه،کد پایین همون کارمورد نظر شما رو می کنه


private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
TreeNode nod;
if (e.Node.Checked == true && e.Node.FirstNode != null)
{
nod = e.Node.FirstNode;
while(nod != null)
{
nod.Checked = true;
nod = nod.NextNode;
}
}
}

Sal_64
جمعه 12 مهر 1387, 16:50 عصر
سلام
با تشکر از جواب شما
کد رو اینطور تغییر دادم


private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
TreeNode nod;
if (e.Node.Checked == true && e.Node.GetNodeCount(true) > 0)
{
nod = e.Node.FirstNode;
while(nod != null)
{
nod.Checked = true;
nod = nod.NextNode;
}
}
}

و یه سوال دیگه با استفاده از کد بالا چطور میشه بررسی کرد کدوم نودها تیک خوردن ؟


با تشکر

SMRAH1
جمعه 12 مهر 1387, 18:22 عصر
سلام
شاید دوستان استفاده از تابع بازگشتی را توصیه کنند (هر گره والد با فراخوانی یک تابع،شمارش فرزندانش را انجام می دهد که هر فرزند دوباره در نقش یک والد ظاهر می شود.) اما من استفاده از پشته (stack) را توصیه می کنم.نمونه زیر برای این منظور است :


private void button4_Click(object sender, EventArgs e)
{
TreeNode nod;
string str = "";
System.Collections.Stack st = new System.Collections.Stack();

nod = treeView1.Nodes[0];
while (nod != null || st.Count != 0)
{
if (nod != null)
{
if (nod.FirstNode != null)
{
st.Push(nod);
nod = nod.FirstNode;
continue;
}
}
else
{
nod = (TreeNode)st.Pop();
}

str += string.Format("{0}\t:\t{1}\t{2}\n", nod.Name, nod.Text,nod.Checked);
nod = nod.NextNode;
}
MessageBox.Show(str);
}

تنها نکته این روش در این است که پردازش از عمق به سطح است یعنی برنامه ابتدا گره های فرزند را پردازش می کند و پس از خاتمه تمام گره های فرزند،گره والد را پردازش می نماید(البته این مسئله قابل تغییر است).

Sal_64
جمعه 12 مهر 1387, 20:03 عصر
سلام
بازم تشکر :قلب:

آقا یه سوال دیگه می خوام در صورتیکه تمام فرزندان یک نود از حالت انتخاب در اومدن
والد (فقط یه سطح بالاتر) اگه انتخاب هست از حالت انتخاب در آد


با تشکر

SMRAH1
شنبه 13 مهر 1387, 05:28 صبح
می تونی از این کد استفاده کنی،البته یک باگ کوچیک داره ولی قابل چشم پوشی است:


private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
TreeNode nod;

if (e.Node.Checked == true && e.Node.FirstNode != null)
{
nod = e.Node.FirstNode;
while(nod != null)
{
nod.Checked = true;
nod = nod.NextNode;
}
}

if (e.Node.Checked == false && e.Node.Parent != null)
{
bool bCheck = false;
nod = e.Node.Parent.FirstNode;
while (nod != null && bCheck == false)
{
bCheck |= nod.Checked; ;
nod = nod.NextNode;
}
if(e.Node.Parent.Checked != bCheck)
e.Node.Parent.Checked = bCheck;
}
}

Sal_64
شنبه 13 مهر 1387, 13:42 عصر
سلام

باز هم تشکر :قلب:

هنوز فرصت نکردم کد بالا رو امتحان نکردم



یه سوال دیگه داشتم

ترکیب شماره level و index هر نود در tree view منحصر بفرده ، درسته ؟

من می خوام با استفاده از ترکیب این دو به نود خاصی دسترسی پیدا کنم

و خاصیت checked اون رو تغییر بدم

آیا این راه امکان پذیره ؟


با تشکر

SMRAH1
شنبه 13 مهر 1387, 19:27 عصر
ترکیب شماره level و index هر نود در tree view منحصر بفرده نیست
مثلا در درخت زیر

A
----AA
B
----BBهر دو گره AA و BB دارای index صفر و level یک هستند.در واقع index فقط وضعیت این گره رو در گره های فرزند پدرش مشخص می کند و level عمق گره رو مشخص میکنه.این دوتا همونطور که مشاهده می کنند در گره های بیشماری تکراری هستند.تنها را انحصار هر گره داشتند سلسه مراتب نامها (Name) هر گره از درخت است.توجه کنید که دو گره متفاوت ممکن است فرزندان هم نام داشته باشند ولی مسیر نامی هر گره (مسیر حاصل متن یا text مد نظر نیست بلکه فقط مسیر حاصل از نام ها مد نظر است) می تواند یک توالی منحصر به فرد تولید کند.

Sal_64
شنبه 13 مهر 1387, 22:23 عصر
سلام
تشکر
درسته
برای دسترسی به text نودها با fullpatch امکان پذیره
چطور به مسیر نامی یک نود دسترسی داشته باشم ؟


با تشکر

SMRAH1
یک شنبه 14 مهر 1387, 04:52 صبح
دوست من از اینکه مطرح شدن این تاپیک باعث شد یکی از اشتباهات من برطرف بشه ازت ممنونم.
تا امروز من فکر می کردم،مسیر نامی ،یکتا است یعنی در هر عمق،فقط یک نام گره اعتبار دارد (قبلا بحث شد) ولی الان که تست کردم دیدم اینطور نیست و می توان گره هایی داشت که هر دو فرزند یک والد بوده و دارای نام و متن یکسان باشند.در نتیجه سلسله مراتبی نامی هم ،راه خوبی برای یکتا بودن نیست.من سلسله مراتب index رو پیشنهاد می کنم (مطمئنا این دیگر یکتا است).در هر حال این دو سلسله مراتب را باید خودت ایجاد کنی (مانند FullPath که سلسسه مراتب متنی را می دهد،برای نام یا index یا ... وجود ندارد).
برای این موضوع روش زیررو پیشنهاد می کنم:


private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
TreeNode nod;
string str1 = "";
string str2 = "";

nod = e.Node;
do
{
str1 = nod.Name + "\\" + str1;
str2 = nod.Index.ToString() + "\\" + str2;
nod = nod.Parent;
} while (nod != null);
MessageBox.Show(str1 + "\n" + str2);
}

Sal_64
دوشنبه 15 مهر 1387, 00:04 صبح
سلام

خواهش :چشمک:
لطف کردید :تشویق:
با این کد شما چطور میشه یه نود رو انتخاب کرد (چک زد) ؟؟ :بوس:

با تشکر

SMRAH1
دوشنبه 15 مهر 1387, 07:40 صبح
سلام

به نظر من بهتره ترتیب index ها رو ذخیره کنی تا بتونی یک گره رو پیدا کنی.

Sal_64
سه شنبه 16 مهر 1387, 09:22 صبح
سلام
آقا یه دنیا تشکر :قلب:
بازم یه زحمت داشتم

میشه کدی که در پست چهارم هست(استفاده از پشته) به شکلی تغییر داد که فقط چک خوردن برگها (نود های بدون فرزند) رو چک کنه ؟


با تشکر

SMRAH1
سه شنبه 16 مهر 1387, 13:12 عصر
سلام

با توجه به کد پست 4،باید تغییری شبیه این انچام بدی

if(nod.GetNodeCount()==0)
str += string.Format("{0}\t:\t{1}\t{2}\n", nod.Name, nod.Text,nod.Checked);

موفق باشی

Sal_64
پنج شنبه 18 مهر 1387, 12:08 عصر
سلام

یه دنیا تشکر :خجالت:



دو سوال دیگه داشتم

شما گفتید که برای انتخاب(تیک زدن) یک نود به وسیله index ها عمل کنم

می خواستم ببینم دستورش چیه

یعنی چطور می تونم بگم که نودهایی که ترتیب index اونا به ترتیب (0/2/3/4) و (0/3/3) و (0/6/1/..) یعنی با طول های متفاوت رو تیک بزنه ؟

و سوال دیگه چطور این شرط بنویسم

اگه تیک یه نود فرزند برداشته شود (اگه نود فرزند از انتخاب خارج شود)

با این دستور امتحان کردم اما ..

if ( e.Node.Checked == false && e.Node.GetNodeCount(true) < 0 )با تشکر

SMRAH1
پنج شنبه 18 مهر 1387, 12:51 عصر
سلام

اول سئوال دومت: عبارت درست رو در زیر آورده ام (علامت > باید به مساوی تبدیل بشه یعنی)


if ( e.Node.Checked == false && e.Node.GetNodeCount(true) == 0 )

اما در مورد اول هم می تونی از تابع زیر استفاده کنی :


private void button6_Click(object sender, EventArgs e)
{
try
{
ChangeCheckTreeView(treeView1, "1\\", true);
ChangeCheckTreeView(treeView1, "1\\2\\0", true);
ChangeCheckTreeView(treeView1, "2\\0\\", true);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message,"",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}

private void ChangeCheckTreeView(TreeView tv, string sPath, bool bCheck)
{
string[] str = sPath.Split(new char[]{'/','\\'});
if(str.Length < 1 )
throw new Exception("Please inset path like 0/1/2");

TreeNode nod;
int i = 1,j,k;
try
{
nod = tv.Nodes[Int32.Parse(str[0])];
while (nod != null && str.Length > i && str[i]!="")
{
k = Int32.Parse(str[i]);
nod = nod.FirstNode;
for (j = 0; j < k; j++)
nod = nod.NextNode;
i++;
}
}
catch(Exception e)
{
throw new Exception(
string.Format("Error in node {0} in deep {1} \n {2}", str[i], i, e.Message));
}

if(nod==null)
throw new Exception("Node not available");

nod.Checked = bCHeck;
}
البته اینها یک پیشنهاده و شاید راه بهنری هم باشد.

موفق باشید