by Chad
24. November 2009 11:55
I’m a big fan of Extension Methods and today I found another use for them while discussing the Managed Extensibility Framework with my friend Matt Lowrance. I previously thought that there was little reason to add extension methods to types that you control the source code for. The idea being that if you have access to the source code, it’s better to extend the type directly since you’ll have access to private state.
Today’s epiphany is that in a loosely coupled system, Extension Methods can be used to hide that loose coupling. For example consider the diagram to the right. I have an ObjectContainer class that is unaware of my CustomObject class. Additionally, CustomObject may be completely unaware of ObjectContainer.
Using an extension method, I can call GetCustomObjects() on an instance of ObjectContainer and receive an array of CustomObject. With this syntax, it appears that the ObjectContainer is aware of CustomObject, but in reality it isn’t. The only type that is tightly coupled is the static ExtensionMethods class that must be aware of both types.
by Chad
6. November 2009 12:14
Recently, I wanted to add a custom tooltip to my WPF application. I wanted the tooltip to display some details about a record and provide buttons that could be clicked to perform some actions on that record. It turns out that this is a very simple thing to do, but because I started with the idea of a tooltip it was a difficult road to my final solution. It appears that several others on the internet have experienced the same situation as I did, so I decided to blog about it.
First Attempt
Starting with the ToolTip, I quickly found that as I moused over the rows, my custom tooltip would display with the buttons. When I tried to click a button the tooltip would move to the next record in my list; effectively forcing me to chase the control around the screen. So I thought to myself, let’s try activating the tooltip on a right-click and preventing it from automatically closing. A quick search in my favorite search engine indicated that this was a misuse of the ToolTip control.
<!-- Source Code Reenactment: !!!THIS DOESN’T WORK!!! -->
<TextBlock.ToolTip>
<ToolTip>
<ToolTip.Template>
<ControlTemplate>
<Button>Do Something</Button>
</ControlTemplate>
</ToolTip.Template>
</ToolTip>
</TextBlock.ToolTip>
Solution
With a little research, I found that the functionality that I was looking for came with the ContextMenu and Popup controls. Both appeared that they’d solve my problem. Both allowed me to display content floating outside of the visual tree and both will accept focus. I ultimately decided to use the ContextMenu because it has built-in right-click support and will automatically hide itself when I click outside of it.
<TextBlock.ContextMenu>
<ContextMenu>
<ContextMenu.Template>
<ControlTemplate>
<Border Background="Black" CornerRadius="10">
<Button Margin="5">Do Something</Button>
</Border>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>
</TextBlock.ContextMenu>
Now, when I right-click my record, a context menu (that doesn’t look like your traditional context menu) displays. I can fully interact with any controls in my ControlTemplate. When a button (with an event handler) is clicked or when I click outside of the ContextMenu, the menu hides itself. Exactly what I wanted.
I hope that this saves someone some time!