WordPress database error: [INSERT, UPDATE command denied to user '51213-2'@'10.10.20.88' for table 'wp_options']INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('_transient_doing_cron', '1715964198.8947949409484863281250', 'yes') ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)
<\/a>We have seen in a previous post<\/a> that WPF 4.5 enable the use of custom markup extensions to provide event handlers. <\/p>\n In this post we’ll see that we can execute a method on the DataContext of the control when an event is raised using this new ability of the MarkupExtension. <\/strong><\/p>\n With some tiny modifications you can run it on Silverlight too !<\/p>\n <\/p>\n For a start, I suggest you to read my first post describing “markup extensions for events in WPF 4.5”. As already said, the DataContext may not be available when the MarkupExtension is used so it is not possible to register directly a Delegate on the ViewModel because we do not have it.<\/p>\n So the tip I use is to create a proxy handler on the markup extension itself. When this handler is called, I will retrieve the viewModel from the DataContext because it will then be set. From it I am able to get the targeted method trough reflection. Then I just have to execute the method if it truly exists.<\/p>\n The name of the method to call is passed in the constructor of the extension and is exposed as a property named ActionName<\/em>.<\/p>\n It also can be found on my dropbox folder after registration<\/a>. public override object ProvideValue(IServiceProvider serviceProvider) targetProvider.TargetObject as FrameworkElement; var targetEventAddMethod = targetProvider.TargetProperty as MethodInfo; \/\/Retrieve the handler of the event \/\/Retrieves the method info of the proxy handler \/\/Create a delegate to the proxy handler on the markupExtension return returnedDelegate;<\/p>\n }<\/p>\n void MyProxyHandler(object sender, EventArgs e) \/\/get the method on the datacontext from its name Use it is simplier thant to create it ! You simply have to use the markupExtension as you would declare a Binding in the XAML: For the record, here is the method I created on my ViewModel : This example leads to really funny things \ud83d\ude42 :How does it work ?<\/h3>\n
\nThe code used is based on the one presented in this previous post.<\/p>\nThe code !<\/h3>\n
\n[csharp]
\npublic class Call : MarkupExtension
\n{
\n public string ActionName { get; set; }
\n public Call(string actionName){ ActionName = actionName; }<\/p>\n
\n {
\n IProvideValueTarget targetProvider = serviceProvider
\n .GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
\n if (targetProvider == null)
\n throw new InvalidOperationException(@"The CallAction extension
\n can’t retrieved the IProvideValueTarget service.");<\/p>\n
\n if (target == null)
\n throw new InvalidOperationException(@"The CallAction extension
\n can only be used on a FrameworkElement.");<\/p>\n
\n if (targetEventAddMethod == null)
\n throw new InvalidOperationException(@"The CallAction extension
\n can only be used on a event.");<\/p>\n
\n ParameterInfo[] pars = targetEventAddMethod.GetParameters();
\n Type delegateType = pars[1].ParameterType;<\/p>\n
\n MethodInfo methodInfo = this.GetType().GetMethod("MyProxyHandler",
\n BindingFlags.NonPublic | BindingFlags.Instance);<\/p>\n
\n Delegate returnedDelegate =
\n Delegate.CreateDelegate(delegateType, this, methodInfo);<\/p>\n
\n {
\n FrameworkElement target = sender as FrameworkElement;
\n if (target == null) return;
\n var dataContext = target.DataContext;
\n if (dataContext == null) return;<\/p>\n
\n MethodInfo methodInfo = dataContext.GetType()
\n .GetMethod(ActionName, BindingFlags.Public | BindingFlags.Instance);
\n methodInfo.Invoke(dataContext, null);
\n }
\n}
\n[\/csharp]<\/p>\nHow to use it ?<\/h3>\n
\n[xml]<Grid PreviewMouseDown="{custMarkup:Call MyMethodToCallOnTheViewModel}"
\n Background="Transparent"\/>[\/xml]<\/p>\n
\n[csharp]public void MyMethodToCallOnTheViewModel()
\n{
\n MessageBox.Show("oh no, you’ve got me …");
\n}
\n[\/csharp]<\/p>\n
\n<\/a><\/p>\nUpdate !<\/h3>\n