PDA

View Full Version : سوال: مشکل با treeview در وین فرم سی شارپ



barman.ar16
شنبه 09 دی 1396, 12:17 عصر
سلام به اساتید عزیز

من توی یکی از فرم هام میخوام بحث سطح دسترسی کاربران رو مشخص کنم که چون تعداد سطح دسترسی ها زیاده میخوام از treeview استفاده کنم

خب حدودا 8 والد دارم که هر کدوم از والدها 4 تا چایلد دارند (البته تا به اینجای کار)

دو تا کار میخوام انجام بدم

اول اینکه اگر یک والد تیک خورد هر 4 تا چایلد هم تیک بخوره
دوم اینکه اگر فقط یه دونه چایلد تیک خورد حتما والدش هم تیک بخوره

ممنون میشم راهنمایی کنید
متشکرم

parvizwpf
شنبه 09 دی 1396, 16:08 عصر
هر نودی یک پراپرتی بنام Parent داره که میشه والدش و هر نودی پراپرتی بنام Nodes داره که میشه فرزندهاش . و هر نودی Checked داره که آیا تیک خورده یا نه . شما با اینها میتونید هر کاری بکنید .
این کد برای وقتیه که اگه تنها یک فرزند انتخاب بشه والدهاش تیک بخورند:
private void SelectParents(TreeNode node, Boolean isChecked)
{
var parent = node.Parent;

if (parent == null)
return;

if (!isChecked && HasCheckedNode(parent))
return;

parent.Checked = isChecked;
SelectParents(parent, isChecked);
}

private bool HasCheckedNode(TreeNode node)
{
return node.Nodes.Cast<TreeNode>().Any(n => n.Checked);
}

barman.ar16
شنبه 09 دی 1396, 16:16 عصر
هر نودی یک پراپرتی بنام Parent داره که میشه والدش و هر نودی پراپرتی بنام Nodes داره که میشه فرزندهاش . و هر نودی Checked داره که آیا تیک خورده یا نه . شما با اینها میتونید هر کاری بکنید .
این کد برای وقتیه که اگه تنها یک فرزند انتخاب بشه والدهاش تیک بخورند:
private void SelectParents(TreeNode node, Boolean isChecked)
{
var parent = node.Parent;

if (parent == null)
return;

if (!isChecked && HasCheckedNode(parent))
return;

parent.Checked = isChecked;
SelectParents(parent, isChecked);
}

private bool HasCheckedNode(TreeNode node)
{
return node.Nodes.Cast<TreeNode>().Any(n => n.Checked);
}

ممنون دوست عزیز
خب من یه خورده گیج شدم الان باید این کدها رو کجا بنویسم
توی aftercheck یا جای دیگه؟
ممنون میشم راهنمایی کنید

parvizwpf
شنبه 09 دی 1396, 18:45 عصر
جاش رو شما باید تشخیص بدی .

barman.ar16
شنبه 09 دی 1396, 19:25 عصر
جاش رو شما باید تشخیص بدی .

خب من میخوام وقتی کاربر یک والد رو تیک زد همه چایلدها تیک بخورن تا نخواد یکی یکی همه رو تیک بزنه و زمانبر باشه
و همچنین اینکه اگر یک چایلد تیک خورد حتما والدش هم تیک بخوره

چون دقیقا اینها معادل یک منو و زیرمنو درون فرم دیگه ام هستند ...
فکر کنم منظورم رو گرفتید
ممنون

parvizwpf
یک شنبه 10 دی 1396, 11:41 صبح
الان حضور ذهن ندارم ولی به احتمال زیاد همون aftercheck

barman.ar16
دوشنبه 11 دی 1396, 19:44 عصر
اساتید عزیز من هنوز مشکلم حل نشد لطفا اگر کسی میدونه راهنمایی کنه

مورد اول : با زدن تیک والد تیک همه چایلدها خورده بشه و با برداشتنش هم اونا برداشته بشن
مورد دوم : با زدن تیک یک چایلد حتما حتما تیک والد بخوره و اگر خواست تیک والد رو برداره تیک همه چایلدها هم برداشته بشه

چرا؟
چون دقیقا معادل والدها در فرم سی شارپی ام منوها هستند و معادل چایلدها زیرمنوها هستند (خب نمیشه زیرمنو باشه ولی منو اش نباشه !!!)

برای مورد اول این رو پیدا کردم که متاسفانه این هم به درستی کار نمی کنه چون اگر یکبار کلیک کنم خوب کار میکنه اما وقتی روی والد دوبار کلیک میشه وضعیت تیک ها برعکس میشه :


private void tvbank_AfterCheck(object sender, TreeViewEventArgs e)
{
tvbank.SelectedNode = null;
if (e.Action != TreeViewAction.Unknown)
{
if (e.Node.Nodes.Count > 0)
{
this.CheckAllChildNodes(e.Node, e.Node.Checked);
}

}
}

private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
{
foreach (TreeNode node in treeNode.Nodes)
{
node.Checked = nodeChecked;
if (node.Nodes.Count > 0)
{
this.CheckAllChildNodes(node, nodeChecked);
}
}
}


ممنون میشم اساتید عزیز راهنمایی کنند متشکرم

barman.ar16
سه شنبه 12 دی 1396, 18:18 عصر
دوستان و اساتید لطفا اگر تجربه ای دارید ممنونم میشم راهنمایی بفرمایید
متشکرم

parvizwpf
سه شنبه 12 دی 1396, 18:37 عصر
ببینید کلیت کار که مشخصه شما دنبال چی هستید؟ الان هم میدونید چطور والد و فرزندها رو بگیرید و ایونتها رو هم که میدونید

barman.ar16
سه شنبه 12 دی 1396, 23:25 عصر
ببینید کلیت کار که مشخصه شما دنبال چی هستید؟ الان هم میدونید چطور والد و فرزندها رو بگیرید و ایونتها رو هم که میدونید

دوست عزیز سوالم که مشخص هست خودم هم بارها تست کردم متاسفانه نتونستم اونی که میخوام دربیارم
کدی که شما گذاشتید هم اصلا به کارم نیومد
در کل ممنون که وقت گذاشتید و راهنمایی کردید

دوستان دیگر در این قضیه تجربه ای ندارند راهنمایی کنن
یعنی موارد مشابه به این قضیه پیش نیومده ... آخه برای درست کردن سطح دسترسی کاربران به نظرم بهترین راه همین treeview هست ؟
ممنون منتظر نظرات دیگر دوستان هستم

parvizwpf
چهارشنبه 13 دی 1396, 08:32 صبح
:لبخندساده:
این رو امتحان کنید طبق این برید جلو اشکالات رو برطرف کنید : من تمام سعیم رو کردم که بهتون بگم که باید با این امکانات کمی سعی وخطا کنید تا کارتون انجام بشه:
private void TreeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
if (treeView1.Enabled)
{
treeView1.AfterCheck -= TreeView1_AfterCheck;

TreeNode node = e.Node;

if (node.Nodes != null)
node.Nodes.Cast<TreeNode>().ToList().ForEach(v => v.Checked = node.Checked);

node = e.Node.Parent;
while (node != null)
{
bool set = e.Node.Checked
? node.Nodes.Cast<TreeNode>()
.Any(v => v.Checked == e.Node.Checked)
: node.Nodes.Cast<TreeNode>()
.All(v => v.Checked == e.Node.Checked);
if (set)
{
node.Checked = e.Node.Checked;
node = node.Parent;
}
else
node = null;
}

treeView1.AfterCheck += TreeView1_AfterCheck;
}
}

barman.ar16
چهارشنبه 13 دی 1396, 21:33 عصر
:لبخندساده:
این رو امتحان کنید طبق این برید جلو اشکالات رو برطرف کنید : من تمام سعیم رو کردم که بهتون بگم که باید با این امکانات کمی سعی وخطا کنید تا کارتون انجام بشه:
private void TreeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
if (treeView1.Enabled)
{
treeView1.AfterCheck -= TreeView1_AfterCheck;

TreeNode node = e.Node;

if (node.Nodes != null)
node.Nodes.Cast<TreeNode>().ToList().ForEach(v => v.Checked = node.Checked);

node = e.Node.Parent;
while (node != null)
{
bool set = e.Node.Checked
? node.Nodes.Cast<TreeNode>()
.Any(v => v.Checked == e.Node.Checked)
: node.Nodes.Cast<TreeNode>()
.All(v => v.Checked == e.Node.Checked);
if (set)
{
node.Checked = e.Node.Checked;
node = node.Parent;
}
else
node = null;
}

treeView1.AfterCheck += TreeView1_AfterCheck;
}
}

ممنون دوست و استاد عزیز
لطف می کنید و وقت میگذارید و راهنمایی می کنید
با این تکه کد هم تقریبا به این مساله دست پیدا کردم ولی کد شما کاملتر بود ممنون


private void tvbank_AfterCheck(object sender, TreeViewEventArgs e)
{
tvbank.SelectedNode = null;
if (e.Action != TreeViewAction.Unknown)
{
if (e.Node.Nodes.Count > 0)
{
this.CheckAllChildNodes(e.Node, e.Node.Checked);
}

}
}

private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
{
foreach (TreeNode node in treeNode.Nodes)
{
node.Checked = nodeChecked;
if (node.Nodes.Count > 0)
{
this.CheckAllChildNodes(node, nodeChecked);
}
}
}

ولی یه مشکل اساسی دارم اون هم اینکه وقتی به آرامی روی والد کلیک می کنم یعنی بصورت تک کلیک های با فاصله از هم همه چیز درست کار می کنه اما اگر بلافاصله پشت سر هم روی والد کلیک بشه یعنی مثلا دوبار کلیک سریع اون موقع والد و چایلدها از اون توازنی که براشون در نظر گرفتیم خارج میشن یعنی والد تیک نخورده و چایلدها همگی تیک خوردن (به نظرم به خاطر این میتونه باشه که نود میره توی حالت سلکت یعنی هایلایت میشه و بعد از حالت سلکت در میاد)
اگر خودتون تست کنید متوجه میشید دقیقا چی میگم (یکبار تک کلیک تک کلیک با فاصله روی والد کلیک کنید یکبار دوبار کلیک دوبار کلیک بدون فاصله)

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

parvizwpf
چهارشنبه 13 دی 1396, 22:26 عصر
من حقیقتش سعی کردم یه سرنخ بدم بله خودم در تستم این مشکل رو دیدم بنظر باگ کنترل مایکروسافته

barman.ar16
جمعه 15 دی 1396, 09:34 صبح
من حقیقتش سعی کردم یه سرنخ بدم بله خودم در تستم این مشکل رو دیدم بنظر باگ کنترل مایکروسافته

ممنون بعله به نظر یه باگ میاد

خب با این اوصاف ...
دوستان برای تعیین سطح دسترسی توی برنامه هاتون وقتی تعداد گزینه ها زیاد باشه به جای چک باکس از چی استفاده می کنید؟
ممنون میشم راهنمایی بفرمایید

رامین مرادی
شنبه 16 دی 1396, 09:03 صبح
ممنون بعله به نظر یه باگ میاد

خب با این اوصاف ...
دوستان برای تعیین سطح دسترسی توی برنامه هاتون وقتی تعداد گزینه ها زیاد باشه به جای چک باکس از چی استفاده می کنید؟
ممنون میشم راهنمایی بفرمایید

منم از treeview استفاده کردم. البته دیگه نگفتم اگه تیک والدش زده بشه بچه هاشم تیک بخورن. چون این والد خودش یه منو هست اجازه دادم بعد از انتخابش کاربر زیر منوهاشو تعیین کنه. یا برعکس کاربر همه زیر منو ها رو انتخاب کنه ولی اگه والد تیک نخوده باشه دیگه زیر منو نیست که اون تیک های بچه هاشم تاثیر داشته باشه.