7

I have this xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:l="clr-namespace:My.Windows" > <ObjectDataProvider x:Key="TitledWindow_Test" MethodName="Test" ObjectInstance={x:Type l:TitledWindow}"> <ControlTemplate x:Key="TitledWindowControlTemplateKey" x:Name="PART_ControlTemplate" TargetType="{x:Type l:TitledWindow}" <Rectangle> <Rectangle.Style> <EventSetter Event="Mouse.MouseEnter" Handler="{StaticResource TitledWindow_Test}"> </Rectangle.Style> </Rectangle> </ControlTemplate> </ResourceDictionary> 

And my c# code:

namespace My.Windows { public partial class TitledWindow : Window { public void Test() { MessageBox.Show("Test"); } } } 

The problem is that i get the following error:

Error 1
'ResourceDictionary' root element requires a x:Class attribute to support event handlers in the XAML file. Either remove the event handler for the MouseEnter event, or add a x:Class attribute to the root element.

5
  • What you are trying to do?? Commented Feb 11, 2014 at 17:33
  • I want to add multiply Handlers to Unique Event through XAML Commented Feb 11, 2014 at 17:38
  • @Jovan - Can't you the method in code behind of Resource dictionary? I don't think you can hook ObjectDataProvider like this to RoutedEvent and that too where delegate is of different signature. Commented Feb 11, 2014 at 17:44
  • Well how can i hook to this method or any method..? Commented Feb 11, 2014 at 17:46
  • Check my answer for having code behind in ResourceDictionary. Commented Feb 11, 2014 at 18:06

3 Answers 3

23

Well you can do that by attaching code behind to your ResourceDictionary. Few simple steps to achieve that are:

  • Say ResourceDictionary file name is CustomResources.xaml. Add another file in same directory besides your ResourceDictionary with name CustomResources.xaml.cs. Create partial class CustomResources inheriting from ResourceDictionary.

Declare your handler for MouseEnter and code behind is ready.

using System; using System.Windows; namespace WpfApplication1 { public partial class CustomResources : ResourceDictionary { public void MouseEnter(object sender, EventArgs e) { MessageBox.Show("Test"); } } } 
  • Now, in XAML set x:Class attribute and set handler to MouseEnter.

XAML :

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="WpfApplication1.CustomResources" xmlns:local="clr-namespace:WpfApplication1"> <ControlTemplate x:Key="TitledWindowControlTemplateKey" x:Name="PART_ControlTemplate" TargetType="{x:Type local:TitleWindow}"> <Rectangle> <Rectangle.Style> <Style TargetType="Rectangle"> <EventSetter Event="Mouse.MouseEnter" Handler="MouseEnter"/> </Style> </Rectangle.Style> </Rectangle> </ControlTemplate> </ResourceDictionary> 
Sign up to request clarification or add additional context in comments.

4 Comments

Wait wait... xD This is good alright, but what about if i have defined those methods in my TitledWindow class, coz that is the class that uses this ResourceDictionary?
For that you have to create ICommand on that class and bind here using interactivity triggers to the Command. But, however, directly binding to the method is not possible from ResourceDictionary. Or either you can move this resource completely under Window.Resources section where definitely you can hook handler directly from code behind.
Argh, alright, i guess i will have to use interactivity triggers, i read about them, but i hoped there is something more elegant, thanks however!
First of all great thanks for this question and answer. I have had exactly the same issue, but I wanna have callbacks for checkbox checked or unchecked. I have added the MessageBox as in your answer to see, if the correct callback is called. My problem currently is, that my callback function CheckBox_Checked is called even before and window is displayed and I'm getting an exception. An unhandled exception of type 'System.InvalidOperationException' occurred in PresentationFramework.dll I'm afraid the app has not been fully initialized. Any idea, how I can check init is done?
2

You need to add the x:class attribute and specify where the resource is, and where the event handler would be located. See Is it possible to set code behind a resource dictionary in WPF for event handling? for an example of this.

Comments

2

The problem is that the Template needs to know if what it is being applied to has a MouseEnter. Unfortunately even by applying your x:Type to the template, the xaml compiler doesn't have enough to go on.

I have done something similar before in getting the ResourceDictionary to recognise the properties of what I'm templating to and it looks like I used a style to get around it. Full code in http://winchrome.codeplex.com/SourceControl/latest#WinChrome/UI/VS2012ResourceDictionary.xaml.

<ResourceDictionary ... > <Style x:Key="CloseButtonStyle" TargetType="{x:Type Button}" > ... <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Border x:Name="bd" ....> .... </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True" SourceName="bd"> <Setter Property="Background" TargetName="bd" Value="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"/> ... </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Background" TargetName="bd"> ... </Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> 

However you want to then bind your handler to a method on your objectDataPresenter via a {StaticResource ...} which I'm not sure that you can. Instead you might be better to instead bind onto the DataContext using a normal binding {Binding Path=...}, I think you might still be able to provide the DataContext via the {StaticResource.. }.

1 Comment

But why would the Template needs to know in which class she belongs, when all i tried to do is bind to object and pull its method through StaticResource Key... Btw ALSki if you want to check my: link i answered on your question

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.