Update: in order to execute a script in any open tab inside Chrome, use the executeScript method of the tabs API.

Chrome browser extensions are so cool, that they protect you from accidentally running and adding script to a page that might interfere with the original code of the page. Unfortunately, they don't give you a parameter or option to actually do that, if it is what you actually want. All you can do, by default, is to access the elements in the page document, but not change direct members of window or even document.

I have found the solution on this page: Writing a Google Chrome extension: How to access the global context of the embedding page through a content script.. There is code and explanations for the code, but basically it is a function that injects another function in the real page context and also returns a result.

I had this control that consisted of a textbox and a squigly red line in case of a required value error. In order to do it, I added the textbox and the line to a Grid, without specifying column or row values, so that the line would come above the textbox. It all worked well until I wanted to make the control align to the left, thus growing with the content entered in it. To my surprise, the control would stretch to the content width when in edit mode and go to 202 pixels outside it. The only things in the template were a textbox and a line inside a grid and a border, so I proceeded on inspecting all of their attributes in search for the culprit. It so happens that the Line was it!

Update: The Microsoft guys responded in a day to my bug report, but they couldn't reproduce it. It seems this behavior can be reproduced only in a Grid column with Width="Auto". Frankly, I was a bit surprised to see that, lacking that grid column, a line with Stretch="Fill" and HorizontalAlignment to "Left" would still expand the container to its maximum size. End update.
The code looked like this:

<Style x:Key="StyleRequiredUnderline" TargetType="{x:Type Line}">
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Stretch" Value="Fill"/>
<Setter Property="X1" Value="0"/>
<Setter Property="X2" Value="1"/>
<Setter Property="Y1" Value="0"/>
<Setter Property="Y2" Value="0"/>
<Setter Property="MaxWidth" Value="200"/>
</Style>

<Grid>
<TextBlock x:Name="TextBlock" />
<Line Name="RequiredUnderline" Style="{StaticResource StyleRequiredUnderline}"
/>
</Grid>
As you can see, the line is Left aligned, it has no specified Width, the only giveaway is the Stretch property set to Fill. Now, you think that was the problem, but it was not! See that I have a MaxWidth of 200. That was per request.

It appears that if I remove the MaxWidth setting, the line goes DOWN to the normal size of the parent inner width. MaxWidth, not MinWidth, mind you. Ok, so I've tried some other things. Stretch to None makes the line be 1px long. Setting X2 to 200 makes the line take 200px, same as setting Width. HorizontalAlignment to Stretch makes the line go to the center of the space if it is bigger than the 200 MaxWidth.

The solution? I've bound the Width of the line to the ActualWidth of the TextBlock above. Another option would have been to surround the line with a scrollviewer or some other control that would allow the line to be as long as it wanted without showing a scrollbar or stretching to the size of its content. Either solution seems bad.

Is this a bug? I think so. If the Stretch property should have affected the space the line takes, then it should have done so when MaxWidth was set to Infinity, but it did not. Well, hopes it helps someone. Final code piece for the line:

<Grid>
<TextBlock x:Name="TextBlock" />
<Line Name="RequiredUnderline" Style="{StaticResource StyleRequiredUnderline}"
Width="{Binding ActualWidth,ElementName=TextBlock}" />
</Grid>


Update: The fix I've exemplified above doesn't work when the HorizontalAlignment of the grid is Stretch or has a Width and the TextBox doesn't have a Left HorizontalAlignment. I have tried to replace the Line with a ScrollViewer with hidden scrolling on the horizontal and disabled on the vertical and having a MaxWidth of 200, Inside placing the troublesome Line. I've tried all kinds of panels and combinations of HorizontalAlignment, HorizontalContentAlignment, ClipToBounds, etc. All to no avail.

Finally, the solution was to create a simple control that would ignore the dimensions of the child controls, demanding no space. I named it ClipContainer and here is its source:

public class ClipContainer : ContentControl
{
protected override Size MeasureOverride(Size availableSize)
{
base.MeasureOverride(availableSize);
return new Size(0, 0);
}
}

<Grid>
<TextBlock x:Name="TextBlock" />
<local:ClipContainer>
<Line Name="RequiredUnderline" Style="{StaticResource StyleRequiredUnderline}" />
</local:ClipContainer>
</Grid>
I've put the line in this control, MaxWidth and all, and the control stretched to the size of its container and clipped all of its contents.

Also, like any responsible developer , I went to Microsoft Connect to add this issue as a bug. Here is the bug report. Vote it up if it affects you.

Sometimes, when working with a WPF application, Snoop would crash with the most innovative error messages possible. One of these was 'Object' type does not have a matching DependencyObjectType. Well, of course it doesn't, but where does this come from, why only when I use Snoop and how do I fix it?

I won't bore you with the details, enough said I have traced the problem to an AttachedPropertyBrowsableForTypeAttribute I have used on an attached property. I was using a Resharper Live Template (a snippet) to generate the code for the property and I'd accidentally forgot to set a proper type in the attribute and left the default object.

The thing looked like this:

[AttachedPropertyBrowsableForType(typeof (object))]
Replacing object with my control fixed the Snoop crash.

I had this container that I wanted to handle any mouse click events. So I proceeded on creating an attached property that has a property changed callback in which I would take the element and add a mouse handler to it. Pretty standard stuff, only it didn't quite work. It also blocked any events in the children. As I knew this should have happened in Preview events, not in normal events, I was stumped.

The problem: the attached property was defined with FrameworkPropertyMetadataOptions.Inherits which meant its value applied to all the children, meaning the value changes on all children when I set it on the parent. That meant the handler for the mouse click events was attached to the container and each of its descendants.

I was comparing these two MySQL queries. They looked the same, except for some extra joins and groups, but one was lasting for 5 seconds, the other for 2 minutes. I removed all extra stuff from the long lasting query to get to an almost identical query as the first, only to see it run for two minutes again. The only difference was the type of a WHERE clause. Instead of comparing date with "20101012" (string) I would compare it with 20101012 (integer). Apparently, the type conversion alone was invalidating any use of the index on the date column and made the query last forever. Good to know.

The scenario is that an Image that has its Stretch property set to None still has a different size from the original image source. You check the Padding, the Margin, the VerticalAlignment and HorizontalAlignment properties, you play with the RenderOptions and SnapsToDevicePixels and nothing seems to work. You specify the Width and Height manually and the image is clipped. The problem here, believe it or not, is that the DPI setting of the image source is different from the system DPI setting.

The solution is an ugly thing:

<Image
Stretch="Fill"
Width="{Binding RelativeSource={RelativeSource Self}, Path=Source.PixelWidth}"
Height="{Binding RelativeSource={RelativeSource Self}, Path=Source.PixelHeight}"/>
So set the Stretch to Fill so that it doesn't fill!

Here is the discussion where I got the solution from: How do I keep an image from being stretched when Stretch="None" doesn't work?.

The scenario is easy enough to create: make a Brush, use a Binding as the Color property, use your brush in your app, then start the application and change the system theme. An error "This freezable can not be frozen" will be triggered. The solution is to set x:Shared="False" for the brushes with color bindings.

An entire Microsoft Connect page is devoted to this issue, so get all the details there: Changing system theme throws "This freezable can not be frozen" exception

Update February 2016: The Microsoft Connect page has disappeared. Maybe it was because the bug was marked as "closed - by design", or some other Microsoft site revamp idiocy.

I had this control where a button was displaying a ContextMenu. I wanted to keep the ContextMenu open so I can manipulate its content. I had assumed that the StaysOpen property would do that for me; it did not. Also, I tried using a ContextMenuClosing event approach, only to discover that it is one of those rare "ing" events that doesn't have a Cancel property. I've looked in the sources of ContextMenu and Popup to see just what is going on and I have decided that the design was impossible to patch in order to get the behaviour I wanted.

In the end, the only solution I could find was to inherit from ContextMenu into a new class that would coerce the IsOpen property to true when StaysOpen is set to true. That did the trick. Here is the code:

public class StaysOpenContextMenu:ContextMenu
{
static StaysOpenContextMenu()
{
fixContextMenuStaysOpen();
}

private static void fixContextMenuStaysOpen()
{
IsOpenProperty.OverrideMetadata(
typeof(StaysOpenContextMenu),
new FrameworkPropertyMetadata(false, null,coerceIsOpen));
StaysOpenProperty.OverrideMetadata(
typeof(StaysOpenContextMenu),
new FrameworkPropertyMetadata(false, null, coerceStaysOpen));
}

private static object coerceStaysOpen(DependencyObject d, object basevalue)
{
d.CoerceValue(IsOpenProperty);
return basevalue;
}

private static object coerceIsOpen(DependencyObject d, object basevalue)
{
ContextMenu menu = (ContextMenu)d;
if (menu.StaysOpen)
{
return true;
}
return basevalue;
}

}


Hope it helps people out.

Update:

This solution only works for the body of the ContextMenu, the submenus are something else. However, the submenus are defined in the control template of a menu item, so that can be easily remedied by changing it to your needs. One quick and dirty solution would be to add a trigger that sets the IsSubMenuOpen property to true whenever StaysOpenOnClick is set. Or, if you simply want to freeze a menu in place, change the template so that the mouse click or hover will only trigger IsSubMenuOpen when the parent ContextMenu has StaysOpen to false, while the StaysOpen property of the MenuItem Popup is set to the ContextMenu StaysOpen.

Ok, I am working on the blog to make it more accessible. I've replaced the template, I made all changes in the template from javascript and CSS, not by editing it and I've removed many of the things clogging the site. Not the cats and flies, though :) The light (low band) version of the site is not working anymore. If you want just the content, you can open the RSS feed.

I would like to know what you are thinking about the new look and I hope I will find the time to write interesting posts.

I haven't been the most present of hosts, but then again, I haven't seen much interest for the collaboration page, with its open chat and whiteboard. Therefore I replaced the link to it with the Plugoo chat. The blog desperately needs some refactoring, but not likely that it will happend soon.

I was working on this application and so I found it easy to create some controls as UserControl classes. However, I realised that if I wish to centralize the styling of the application or even move some of the controls in their own control library with a Themes folder, I would need to transform them into Control classes.

I found that there are two major problems that must be overcome:

  1. the named controls in a user control can be accessed as fields in the code behind; a theme style does not allow such direct access to the elements in the control template.
  2. the controls that expose an event may not expose an associated command. In a user control a simple code behind handler method can be attached to a child control event, but in a theme a command must be available in order to be bound.



Granted, when the first problem is solved, it is easy to attach events in the code of the control to the child elements, but this presents two very ugly problems: the template of the control will need to contain the child elements in question and the event will not be declared in the theme, so the behaviour would be fixed as well.

I will solve the handling of events as commands by using a solution from Samuel Jack. The article is pretty detailed, but to make the story short, one creates an attached property for each of the handled events by using a helper class:


public static class TextBoxBehaviour
{
public static readonly DependencyProperty TextChangedCommand =
EventBehaviourFactory.CreateCommandExecutionEventBehaviour(
TextBox.TextChangedEvent, "TextChangedCommand", typeof (TextBoxBehaviour));

public static void SetTextChangedCommand(DependencyObject o, ICommand value)
{
o.SetValue(TextChangedCommand, value);
}

public static ICommand GetTextChangedCommand(DependencyObject o)
{
return o.GetValue(TextChangedCommand) as ICommand;
}
}

then by using a very simple syntax on the control that fires the event:


<TextBox ff:TextBoxBehaviour.TextChangedCommand="{Binding TextChanged}"/>



The problem regarding access to the elements in the template is solved by reading the elements by name from the template. In some situations, like when one uses a control as a source for a data control (like using a TreeView as the first item in a ComboBox), the approach will have to be more complicated, but considering the element is stored in the template of the control, something like this replaces the work that InitializeComponent does inside a UserControl:


[TemplatePart(Name = "PART_textbox", Type = typeof (TextBox))]
public class MyThemedControl : Control, ITextControl
{
private TextBox textbox;

public override void OnApplyTemplate()
{
base.OnApplyTemplate();
textbox = Template.FindName("PART_textbox", this) as TextBox;
}
...


The code is pretty straight forward: use the FrameworkTemplate.FindName method to find the elements in the OnApplyTemplate override and remember them as fields that you can access. The only weird part is the use of the TemplatePartAttribute, which is not mandatory for this to work, but is part of a pattern recommended by Microsoft. Possibly in the future tools will check for the existence of named elements in the templates and compare them against the ones declared in the control source.

The code of a demo project can be downloaded here.

Some other technologies I have used in the project:

  • the RelayCommand class, to make it easier to defined ICommand objects from code without declaring a type for each.
  • the AccessKeyScoper class that allows an IsDefault button to act locally in a panel.

If you google the net for using visual effects in WPF you are very likely to hit BitmapEffects. Well, bad news, BitmapEffect is obsolete and broken in WPF4. Instead you have Effect. The idea is to write (or download) a custom Effect for the things one would normally do using the slow (but easy to use) BitmapEffects. Also, the BitmapEffectGroup doesn't work anymore and has no alternative in WPF4. Bummer! According to Dr. WPF, the framework will try to automatically translate the older BitmapEffects to the new ones. That applies for BlurBitmapEffect and for DropShadowBitmapEffect with a Noise level of 0, for the others... you are on your own.

There were 5 default BitmapEffect classes in WPF3:
  1. BlurBitmapEffect - the WPF4 alternative is BlurEffect
  2. OuterGlowBitmapEffect - the WPF4 alternative in the Microsoft article is BlurEffect, but I have found that it can be replaced by DropShadowEffect with ShadowDepth set to 0
  3. DropShadowBitmapEffect - the WPF4 alternative is DropShadowEffect
  4. BevelBitmapEffect - the WPF4 alternative is a custom class inheriting from Effect.
  5. EmbossBitmapEffect - the WPF4 alternative is a custom class inheriting from Effect.


I found this project when googling to a simpler way of building ShaderEffects: WPF ShaderEffect Generator. Also, a discussion about a Bevel ShaderEffect here led me to this WPF shader library, but it's last release date is somewhere in March 2009.

I am using this WPF control that looks like a headered panel. On the header there is a menu, a button and then, underneath, some content that could be anything. I had this request that, when using the Tab key to navigate, the focus should first come to the button, which is not the first control in the header, then jump to the controls in the content and then jump back to the menu. In other words, to make the menu the last controls that can be reached via the Tab key inside this WPF control.

Well, in WPF there is this class called KeyboardNavigation which has some very useful attached properties: TabIndex (which defaults to int.MaxValue) and TabNavigation (which defaults to Continue). As in Windows Forms, one needs to set the TabIndex to control the navigation order, but the TabNavigation property makes it a lot more versatile and clear as well. In my case, I had to do the following:
  1. Set the entire panel control to KeyboardNavigation.TabNavigation=Local. That allowed me to control the tab index inside the control, otherwise the TabIndex value would have been global to the window
  2. Set the TabIndex of the button to 1. That made the button the first thing to be selected in case I use Tab to navigate in the panel
  3. Set the TabIndex of the content to 2. This set the controls in the content as the next controls to be accessed via the Tab key
  4. Set the TabNavigation value of the content to Local. Without this, the TabIndex value would have made no sense. First of all the content panel has IsTabStop to false and, second, any control inside it would have int.MaxValue set as TabIndex which would work globally in the main control.


This example should make it clear how to use the KeyboardNavigation properties. There is one more, called ControlTabNavigation, which has a misleading name and an ambiguous description. It is not related to a control, the Control in the name comes from the Ctrl key. In WPF one can use Ctrl-Tab to navigate an alternative order thus allowing, in this case, to go directly to the menu, then the button and then the controls in the content area.

I was trying to use a static class of attached properties that I would use inside my WPF control templates, so that every time I need to change them I would only use a setter, not copy paste the entire template and make minute changes. It worked great and I recommend this solution to everybody. So after the refactoring of my control I was shocked to see that in the production application, all my attached properties were throwing binding errors!

The solution was to explicitly use the Path= syntax in the bindings.

{Binding Path=(namespace:ClassName.Property)...
not
{Binding (namespace:ClassName.Property)...

The strange thing is that in the test application everything worked great, so what went different? Apparently the problem is that IXamlTypeResolver (used in PropertyPath) is not finding namespaces unless already registered, as explained here by Rob Relyea. The dude with that Lovecraftian name is the program manager for the WPF & Xaml Language Team.

So if one uses the namespace of the attached property before in some other context or by using the verbose syntax before, it works even with the Path keyword omitted. Not really sure why the verbose syntax works differently though.

Many a time I want that textblocks that get trimmed to display their text as a tooltip. For that, I would make a trigger to set the Tooltip value to the Text value if the textblock has been trimmed. The problem is that there is no property that shows if this is the case.

Googling a bit, I found this article, which apparently works, but also has some problems, as reported by many commenters. Even if it would have worked perfectly, my scenario is too simple to need all that code.

The idea of the original post is simple and I like it, the problem being that convoluted method that computes the width of the text in the textblock. Why would I want to redo all the work that is being done by the framework itself? The width of a textblock with TextWrapping NoWrap should be textBlock.Measure(Size(double.MaxValue,double.MaxValue)). I am sure a more complex scenario can also be serviced by this method, if the height is taken from the TextBlock, but I don't need it.

So here is the entire class, using my measuring method:
public class TextBlockService
{
static TextBlockService()
{
// Register for the SizeChanged event on all TextBlocks, even if the event was handled.
EventManager.RegisterClassHandler(typeof (TextBlock),
FrameworkElement.SizeChangedEvent,
new SizeChangedEventHandler(OnTextBlockSizeChanged),true);
}

public static readonly DependencyPropertyKey IsTextTrimmedKey =
DependencyProperty.RegisterAttachedReadOnly(
"IsTextTrimmed",
typeof (bool),
typeof (TextBlockService),
new PropertyMetadata(false)
);

public static readonly DependencyProperty IsTextTrimmedProperty =
IsTextTrimmedKey.DependencyProperty;

[AttachedPropertyBrowsableForType(typeof (TextBlock))]
public static Boolean GetIsTextTrimmed(TextBlock target)
{
return (Boolean) target.GetValue(IsTextTrimmedProperty);
}

public static void OnTextBlockSizeChanged(object sender, SizeChangedEventArgs e)
{
TextBlock textBlock = sender as TextBlock;
if (null == textBlock)
{
return;
}
textBlock.SetValue(IsTextTrimmedKey, calculateIsTextTrimmed(textBlock));
}

private static bool calculateIsTextTrimmed(TextBlock textBlock)
{
double width = textBlock.ActualWidth;
if (textBlock.TextTrimming == TextTrimming.None)
{
return false;
}
if (textBlock.TextWrapping != TextWrapping.NoWrap)
{
return false;
}
textBlock.Measure(new Size(double.MaxValue, double.MaxValue));
double totalWidth = textBlock.DesiredSize.Width;
return width < totalWidth;
}
}


This would be used with a trigger, as I said at the beginning of the post:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Style.Triggers>
<Trigger Property="Controls:TextBlockService.IsTextTrimmed" Value="True">
<Setter Property="ToolTip" Value="{Binding Text,RelativeSource={RelativeSource Self}}"/>
</Trigger>
</Style.Triggers>
</Style>