Declaring a XAML button programmatically and preventing it from vanishing on mouse over
Sometimes I like to make life difficult for myself, or at least it seems that way. For example, I'm apparently a bit mad, because when writing Windows Store apps I'd sometimes rather declare the various buttons and other UI elements in my C# source code, rather than in XAML. Having an enormous chunk of XAML in my MainPage.xaml file just doesn't make me happy.
So there I was, writing an app that generates buttons and textboxes on the fly from data stored in a XML file (yeah, don't ask) and it was all working great except than when I declared a button, the default action meant the button would disappear on mouse over. Puff - it vanished. Very unsettling.
Here's what I was doing: first I create a button, give it an image, and remove any outline. Then I add an event. For my app's purposes, I was also giving it a unique ID in its tag field and messing with the positioning a little. Don't worry about that part.
Button b = newButton();
var brush = newImageBrush();
brush.ImageSource = newBitmapImage(newUri("ms-appx:///ButtonUp.png"));
b.Height = 32;
b.Width = 32;
b.Background = brush;
b.Margin = newThickness(70, 0, 0, 0);
b.BorderThickness = newThickness(0);
b.Tag = id;
b.Opacity = 0.6;
b.Click += MoveNodeUp_Click;
Of course my first thought was "Huh?" followed by some experiments to trap the OnMouseOver or OnPointerOver events and stop it from flickering away, but no dice. With a deep sigh I resigned myself to having to mess with XAML control templates (have you seen the default control templates? The one for a button goes on for page after page). Then I discovered I could make one simple addition to my XAML to change the default behavior for all Buttons on the page. And that default behavior would prevent the button from flickering. Hurrah! So in case you might find it useful, here's all you need to add to your MainPage.xaml file:
<Page.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Page.Resources>
</Style>
The great thing is that I didn't need to make a single change to my C# code, and the buttons all worked fine.