نیاز بود تا بتوان رخدادهای MouseLeftButtonDown و MouseLeftButtonUp یک TextBox را در Silverlight مدیریت کرد. شاید عنوان کنید که خیلی ساده است! دو روال رخداد گردان مربوطه را اضافه کنید و سپس تعاریف آنها را در کدهای XAML خود قید نمائید. اما واقعیت این است که کار نمیکند! نه؛ کار نمیکند! :)
مشکل از کجاست؟ پاسخی که در
MSDN در این مورد آمده است به صورت زیر میباشد:
"Certain control classes (for example Button) provide control-specific handling for mouse events such as MouseLeftButtonDown. The control-specific handling typically involves handling the event at a class level rather than at the instance level, and marking the MouseLeftButtonDown event data's Handled value as true such that the event cannot be handled by instances of the control class, nor by other objects anywhere further along the event route. In the case of Button, the class design does this so that the Click event can be raised instead."
به عبارتی رخداد Click زحمت کشیده و رخدادهای MouseLeftButtonDown و MouseLeftButtonUp را نیز handled معرفی میکند و دیگر روال رخدادگردان شما فراخوانی نخواهد شد (در WPF هم به همین صورت است) و موارد ذکر شده در visual tree یک TextBox منتشر نمیگردند.
راه حل چیست؟حداقل دو راه حل وجود دارد:
الف) یک کنترل TextBox سفارشی را از کنترل TextBox اصلی باید به ارث برد و رخدادهایی را که توسط رخداد Click به صورت handled معرفی شدهاند، unhandled کرد:
public class MyTextBox : TextBox
{
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
e.Handled = false;
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
e.Handled = false;
}
}
ب) یا امکان گوش فرا دادن به رخدادهای handled نیز میسر است. فقط کافی است این گوش فرادهنده را توسط متد AddHandler که پارامتر آخر آن به true تنظیم شده است (رخدادهای handled نیز لحاظ شوند)، معرفی کرد:
public MainPage()
{
InitializeComponent();
txt1.AddHandler(FrameworkElement.MouseLeftButtonDownEvent,
new MouseButtonEventHandler(txt1_MouseLeftButtonDown), true);
}
private void txt1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//do something
}