PDA

View Full Version : سوال: بدست آوردن مقدار یک Node



water_lily_2012
پنج شنبه 07 مهر 1390, 08:50 صبح
سلام
می خواهم وقتی با موس روی یکی از Node های TreeView می روم مقدار Node را بدهد.
نمی خواهم روی Node کلیک کنم. فقط اگر موس روی هر node رفت و مقداری مثلا حدود 1 ثانیه توقف کرد مقدار همان Node را بدهد.

A.Karimi
جمعه 08 مهر 1390, 17:57 عصر
فکر می‌کنم بهترین راه حل استفاده از رویداد MouseMove بر روی کل TreeView باشد. همانطور که می‌دانید RoutedEvent ها قابلیت عمل کردن به صورت Bubbling و Tunelling را دارند و این یعنی شما در رویداد TreeView می‌توانید بفهمید که کدامیک از فرزندان این کنترل تحت تاثیر این رویداد بوده‌اند یا این رویداد را ایجاد کرده‌اند.

در عمل اگر یک TreeView با نام treeView1 داشته باشید می‌توانید در رویداد MouseMove کد زیر را بزنید تا آیتم Hover شده را داشته باشید:


private object hoverItem = null;
private void treeView1_MouseMove(object sender, MouseEventArgs e)
{
var source = e.Source;
if (source != this.treeView1)
{
// Now mouse is on the something other than the treeView1. It's source!
if (this.hoverItem != source)
{
// TODO: Reset timer
}
this.hoverItem = source;
}
else
{
if (this.hoverItem != null)
{
// TODO: Reset timer
}

this.hoverItem = null;
}
}



و بعد با یک Timer به راحتی می‌توانید مدت زمان مورد نظر برای عملیات را چک کنید. اگر تایمر به آخر رسید و this.hoverItem برابر null نبود، موقع مناسب برای کار شماست.
در کد محل reset کردن تایمر را نیز با TODO مشخص کرده‌ام.

water_lily_2012
شنبه 09 مهر 1390, 09:32 صبح
سلام
خوشحال شدم یک نفر جواب داد.
راستش من می خواهم متن Node را موس روی آن ایستاده را بگیرم. ولی نمی دونم کدام دستور شما متن Node را می دهد.
اگر لطف کنید کدتون را کامل تر کنید تا متن node را هم بدهد.

A.Karimi
شنبه 09 مهر 1390, 11:21 صبح
خیلی ساده‌ست. شما کل node را در اختیار دارید که در متغییر this.hoverItem ذخیره خواهد شد. البته دقت کنید که اگر ماوس بر روی آیتمی نباشد مقدار null خواهد داشت. پس شما با استفاده از کد زیر به متن node دسترسی دارید:


((TreeViewItem)this.hoverItem).Header


البته در صورتی که نمی‌خواهید hoverItem را تبدیل به TreeViewItem کنید می‌توانید کد بنده را به این شکل تغییر دهید:


private TreeViewItem hoverItem = null;
private void treeView1_MouseMove(object sender, MouseEventArgs e)
{
var source = e.Source;
if (source != this.treeView1 && source is TreeViewItem)
{
// Now mouse is on the something other than the treeView1. It's source!
if (this.hoverItem != source)
{
// TODO: Reset timer
}
this.hoverItem = (TreeViewItem)source;
}
else
{
if (this.hoverItem != null)
{
// TODO: Reset timer
}

this.hoverItem = null;
}
}



در این صورت شما به راحتی با دستور زیر به متن node دسترسی دارید:


if (this.hoverItem != null)
{
var text = this.hoverItem.Header;
}

water_lily_2012
شنبه 09 مهر 1390, 22:05 عصر
تشکر از لطفتون
من دقیقا از این کد استفاده کرده ام اما نمی دونم چرا مقدار System.Window.Control را نمایش می دهد.


private TreeViewItem hoverItem = null;
private void PanelTreeView_MouseMove(object sender, MouseEventArgs e)
{
var source = e.Source;
if (source != this.PanelTreeView && source is TreeViewItem)
{
// Now mouse is on the something other than the treeView1. It's source!
if (this.hoverItem != source)
{
// TODO: Reset timer
}
this.hoverItem = (TreeViewItem)source;
}
else
{
if (this.hoverItem != null)
{
var text = this.hoverItem.Header;
SearchTextBox.Text = text.ToString();
// TODO: Reset timer
}
this.hoverItem = null;
}
}

A.Karimi
یک شنبه 10 مهر 1390, 01:01 صبح
احتمالاً شما داخل Header هر Node یک کنترل دیگر مثل Image یا چیزی شبیه آن قرار دادید و هر Node را دقیقاً برابر با یک رشته (string) ساده قرار ندادید.

در این صورت با Debug کردن بر روی Header می‌توانید چک کنید که این Control از چه جنسی است. ممکن است بتوانید آنرا به کنترل مورد نظر خود Cast کرده و از خصیصه دیگری از آن استفاده کنید. مثلاً اگر کنترل گفته شده از نوع TextBlock بود کد زیر کارساز است:


var text = ((TextBlock)this.hoverItem.Header).Text;

water_lily_2012
یک شنبه 10 مهر 1390, 15:39 عصر
من از یک آیکون برای هر Node استفاده کرده ام. حالا چه کار کنم.

A.Karimi
یک شنبه 10 مهر 1390, 16:29 عصر
شما دقیقاً میخواهید چه چیزی را بدست آورید؟ لطفاً قطعه کد پر کردن TreeView را قرار داده و مشخص کنید که می‌خواهید با ایستادن ماوس بر روی یک Node چه اطلاعاتی بدست بیاید؟

water_lily_2012
یک شنبه 10 مهر 1390, 17:01 عصر
سلام
متوجه شدم منظور شما چی هست.
من از stackpanel استفاده می کنم و سپس از textBlock

water_lily_2012
یک شنبه 10 مهر 1390, 17:17 عصر
این هم کد من:

TreeViewItem child = new TreeViewItem();
StackPanel pan = new StackPanel();

pan.Orientation = Orientation.Horizontal;
BitmapImage icon = new BitmapImage(new Uri(appStartPath + "\\Icon.png", UriKind.RelativeOrAbsolute));
Image image = new Image();
image.Height = 18;
image.Source = icon;
pan.Children.Add(image);

pan.Children.Add(new TextBlock(new Run(" " + header)));
child.Header = pan;
return child;

water_lily_2012
دوشنبه 11 مهر 1390, 17:07 عصر
دوست عزیز
من کد مربوط به پر کردن TreeView را قرار دادم.
و حالا مثلا اگر 5 تا Node وارد این TreeView کنم مانند زیر:

reza
hasan
majid
ali
mohamad
حالا می خواهم موس روی هر کدام از این Node ها ایستاد نام Node را به من بدهد.
مثلا اگر روی node سوم بود majid اگر اول بود Reza و ...

A.Karimi
سه شنبه 12 مهر 1390, 11:20 صبح
می‌توانید به شکل زیر به متن header دسترسی داشته باشید (فرض کنیم که this.hoverItem طبق صحبت‌های قبلی آماده است):


var stackPanel = (StackPanel)this.hoverItem.Header;
var textBlock = (TextBlock)stackPanel.Children[1];
var header = ((Run)textBlock.Inlines.FirstInline).Text.Substrin g(1); // I put Substring to remove the space you add before header.

water_lily_2012
سه شنبه 12 مهر 1390, 17:46 عصر
دستت درد نکنه. حل شد.
فقط یه عیب داره. با حرکت موس روی متن node ها کار نمی ده. البته زیاد مهم نیست.
یک مشکل دیگر دارم. شما که تا حالا لطف کرده اید. لطفا این یک مشکل مرا هم حل کنید. حدود 2 هفته هست درگیر این treeview شدم.

راستش حالا می خواهم وقتی موس روی هر node رفت یک فرم کنار موس باز بشه و با توجه به مقدار که از item.Hover بدست می آید، این مقدار را در یک لیست کالکشن پیدا کرده (TreeView توسط یک لیست کالکشن پر می شود و دارای دو ستون هست یکی موضوع که در treeview نمایش داده می شود و دیگری متن موضوع)
و مقدار متن موضوع معادل موضوع را بدست آورده و به فرمی که کنار موس باز می شود ارسال کند.
با حرکت موس روی هر node ، به فرم کنار موس اطلاعات جدید داده شود.

این هم کد پر کردن treeView:


List<BLL.BLLExplain> listExplain;

for (int index = 0; index < listExplain.Count; index++)
{
TreeViewItem tvi = CreateTreeViewItem(listExplain[index].TitleExplain);
PanelTreeView.Items.Add(tvi);
}

با تشکر

A.Karimi
پنج شنبه 14 مهر 1390, 20:50 عصر
برای پیدا کردن آیتم می‌توانید به این صورت عمل کنید:


string titleExplainToFind = "[متنی که از نود مورد نظر بدست آوردید]";
var explatin = listExplain.FirstOrDefault(le => le.TitleExplain == titleExplainToFind);
if (explain != null)
{
// explain is a BLL.BLLExplain object which your looking for.
}


البته من پیشنهاد می‌کنم کلاً روش کار را تغییر داده و از Binding استفاده کنید و برای نمایش هر آیتم Tree از DataTemplate. در این صورت می‌توانستید Tooltip را نیز در همان DataTemplate نمایش دهید و درگیر پیدا کردن Nodeی که Hover شده نباشید.

در مورد اینکه با رفتن ماوس بر روی متن این عملیات کار نمی‌کند علت این است که TextBlock بچه‌ی Node مورد نظر است و شما با طی کردن پدرهای Node پیدا شده تا زمانی که به یک شی TreeViewItem برسید می‌توانید به آن دست پیدا کنید. متاسفانه وقت کافی برای نوشتن کد آن ندارم. اگر وقت شد حتماً ارسال می‌کنم.

water_lily_2012
پنج شنبه 21 مهر 1390, 12:06 عصر
سلام دوست عزیز
واقعا تشکر از راهنمایی های خوبتون
بهرحال این قسمت را نوشتم.
چند روزی درسهام زیاد بود. و نتوانستم آخرین پست را بررسی کنم.

Amir Oveisi
پنج شنبه 21 مهر 1390, 14:17 عصر
يک توصیه جدی:
هیچ وقت به دنبال "فقط نتیجه گرفتن" نباشید. سعی کنید از راه های درست استفاده کنید. در این کاری که شما انجام دادید تقریبا از هیچکدوم از قابلیت های wpf استفاده نکردید و کاملا به شیوه win app سعی کردید مشکلتون رو حل کنید. به جز مورد استفاده از قابیلت routed event‌های wpf.
این کار رو میتونستید خیلی راحت تر از طریق Template ها و Trigger ها و Binding حلش کنید (همون طور که A.Karimi هم اشاره کردند).
امیدوارم در کارهای بعدی سعی کنید از پایه مسله رو به شیوه یک wpf app طراحی و حل کنید.
موفق باشید :)

water_lily_2012
پنج شنبه 21 مهر 1390, 15:36 عصر
راستش این چیزی که شما فرمودید را بلد نیستم. خوب بزرگواری کنید و آموزش دهید.
با تشکر

Amir Oveisi
پنج شنبه 21 مهر 1390, 16:12 عصر
شما ابتدا باید مبانی WPF رو بخوبی یاد بگیرید و تفاوت ها رو با Win App‌بدونید چی هست و درک درستی از WPF‌داشته باشید. سپس در طول مسیر یادگیری به این مراحل که در پست های قبلی گفته شده خواهید رسید. الان نمیشه بدون وجود پیش نیاز ها اقدام به یادگیری این دسته از مطالب نمود.
برای یادگیری مقدمات WPF‌از تاپیک آموزش WPF مقدماتی تا متوسط که در اعلان ها هست میتونین استفاده کنید.
موفق باشید