WPF Custom Controls Construction,Triggers and Events

G.Y picture G.Y · Feb 19, 2013 · Viewed 12.7k times · Source

I want to build a new custom control. I found few tutorials that gave me some clue of how to achieve this. As I understand it, creating a new custom control is always done by extending a current one, and it is even possible to extend a control from the very basic levels of the hierarchy, in example, you can even extend:

  • UIElement
  • FrameworkElement
  • Control
  • ContentControl
  • HeaderedContentControl
  • ItemsControl
  • Selector
  • RangeBase

As written in the following tutorial: http://wpftutorial.net/HowToCreateACustomControl.html

So, I followed the tutorial and created a new project of type Custom Control Library, got my generic .xaml and my code behind. So far so good.

There are 3 types or categories of events I can distinguish between.

  1. Events that are consumable by the window (or container) that will use my control: those are the events I would like to expose to the outside. How to write those?

  2. Events that are related to the control itself and not being exposed outside; for example, if the mouse is over my control and I would like to react to that. I can do that in the XAML:

    <ControlTemplate.Triggers>
      <Trigger Property="IsMouseOver" Value="true">  
        <Setter Property="Fill" TargetName="LeftTraingularIndicator">  
          <Setter.Value>  
            <SolidColorBrush Color="Yellow" />  
          </Setter.Value>  
        </Setter>
      </Trigger>
    </ControlTemplate.Triggers>  
    

Assuming of couse I have an element with the fill property in my ControlTemplate which is named x:name="LeftTraingularIndicator"

Questions:

Now I want to react in my XAML to IsMouseDown. How do I do that? There is no "IsMouseDown" Trigger. Furthermore what if I want to react to that in the code behind? And even further what if I want to change LeftTraingularIndicator "Fill" from the code behind?

  1. Events that related to sub-elements which are part of the visual construction of my ControlTemplate, in example what if I want to react to "IsMouseOver" of "LeftTraigularIndicator" in XAML / or even in Code Behind? Maybe even both.

I am attempting for 2 days now... feeling I am missing something in my understanding of how things work. Didn't find any tutorial that deeply explains those questions.

I would like to see a few lines of example for each of the questions I surfaced here.

Thanks.

Answer

G.Y picture G.Y · Feb 19, 2013

After extensive research...

1) Exposing events to the outside... Simply as if you were exposing from any other class.

public delegate void myDelegate(int someValue);  
public event myDelegate myEvent;

and somewhere in your code:

if(myEvent!=null)
  myEvent(5);

Nothing new in that part.

2) From the code behind create an instance constructor

public MyCustomControl()
{
    MouseMove += MyCustomControl_MouseMove;
}


void MyCustomControl_MouseMove(object sender, MouseEventArgs e)
{
   //now you can react to the movement of the mouse.
   //if for example I want to address an element, let's say a rectangle:

   var ele = (Rectangle)Template.FindName("myRect",this);
   ele.Fill=myNewBrush;

   // provided that we have an element named "myRect" (x:name="myRect") in
   // the generic.xaml style->Control Template-> which corresponds to that name.

}

3) Not recommended - as it belong to the scope of user-controls and not custom controls. Custom controls are the "atoms", user controls are more suitable to the purpose of combining controls.

But not impossible...

var myButton = (Button)Template.FindName("myButton",this);
myButton.OnMouseMove += ....

Just keep in mind that:

  • Anything that should be known in the code-behind must be named.

  • Your xaml should have no knowledge of what the code behind do. (except! - keep reading)

  • Parts that should be known in the code-behind must have the correct name when you design your XAML.

I truly hope this will help others who get a "wall" when trying to develop their own custom-controls.