I am creating a tab control as part of DataJuggler.WPF.Controls located at http://datajugglercontrols.codeplex.com
I am not sure why, but the tab control for WPF is so much more complicated than the Windows version of this same control.
For some reason, for my control to update, I have to change the control.Template programmatically every time I need a change to take effect in the control.
I have found extension methods that everyone else say works for them, but the only way I can get anything to work is change the template. This is so primitive, I have to create a template using a string builder to change 3 words of text or the background image.
But I will vent about WPF and how unefficient is later.
My problem is now after I change the template for the TabButton UserControl (part of my project, not a WPF TabButton) the click event stops working.
I added this to no avail:
// Setup the click event this.LabelButton.Click += LabelButton_Click;
I have read a dozen posts about Event Setter, my code gives me another error 'Failed to create a handler for the text 'LabelButton_Click' so I had to take out the event setter.
Here is the Xmal for the UserControl:
<UserControl x:Class="DataJuggler.WPF.Controls.TabControls.TabButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="48" d:DesignWidth="200"><Grid x:Name="TabButtonGrid"><Grid.Background><ImageBrush ImageSource="../Images\DisabledTab2.png"></ImageBrush></Grid.Background><Button Name="LabelButton" Click="LabelButton_Click"><Button.Template><ControlTemplate TargetType="{x:Type Button}"><Label Name="Label" Content="Button" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalAlignment="Bottom" FontFamily="Verdana" FontWeight="Bold" FontSize="14" Margin="0,-6,0,6"></Label></ControlTemplate></Button.Template></Button></Grid></UserControl>
Here is the Setter for 'Selected' on the tab control, which is what changes the background image by
changing the template:
/// <summary>
/// This property gets or sets the value for 'Selected'.
/// </summary>
public bool Selected
{
get { return selected; }
set
{
// set the value
selected = value;
// display the TabImage
DisplayTabImage(selected);
}
}The DisplayTabImage is where I change out the Template for the TabButton user control:
/// <summary> /// This method Display Tab Image /// </summary> public void DisplayTabImage(bool selected) { // Create the control template ControlTemplate template = CreateControlTemplate(selected, this.ButtonText); //// Update the template this.Template = template; // Add the click event back (doesn't work) this.LabelButton.Click += LabelButton_Click; }
And the method for CreateControlTemplate:
/// <summary>
/// This method creates the Control Template
/// </summary>
private ControlTemplate CreateControlTemplate(bool selected, string buttonText)
{
// initial value
ControlTemplate template = null;
try
{
// Create a string builder
StringBuilder sb = new StringBuilder();
// append each line to create the control template
sb.Append("<ControlTemplate ");
sb.Append("xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' ");
sb.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' TargetType=\"{x:Type UserControl}\">");
sb.Append("<Grid x:Name=\"TabButtonGrid\">");
sb.Append("<Grid.Background><ImageBrush ImageSource=\"../Images/[ImageName]\"></ImageBrush></Grid.Background>");
sb.Append("<Button Name=\"LabelButton\">");
sb.Append("<Button.Template><ControlTemplate TargetType=\"{x:Type Button}\">");
sb.Append("<Label Name=\"Label\" Content=\"[ButtonText]\" HorizontalAlignment=\"Stretch\" HorizontalContentAlignment=\"Center\" VerticalAlignment=\"Bottom\" FontFamily=\"Verdana\" FontWeight=\"Bold\" FontSize=\"14\" Margin=\"0,-6,0,6\"></Label>");
sb.Append("</ControlTemplate></Button.Template></Button></Grid>");
sb.Append("</ControlTemplate>");
// set the imageName
string imageName = "DisabledTab2.png";
// if selected
if (selected)
{
// change the imageName
imageName = "BlueTab.png";
}
// create the temp string
string controlTemplate = sb.ToString().Replace("[ImageName]", imageName);
// replace out the buttonText
controlTemplate = controlTemplate.Replace("[ButtonText]", buttonText);
// now load the template using a XmlReader
StringReader stringReader = new StringReader(controlTemplate);
XmlReader xmlReader = XmlReader.Create(stringReader);
template = (ControlTemplate)XamlReader.Load(xmlReader);
}
catch (Exception error)
{
// for debugging only
string err = error.ToString();
}
// return value
return template;
}
The click works the first time on a button I have not 'Selected', but a button that has the template changed, stops being clickable.
Why did WPF over complicate clicking, something that has been so simple since Visual Basic version 1,
and now with Progress I have routed events, I have event setters which I cannot figure out and a simple button click doesn't work. Way to go with progress WPF!
Are Punch cards going to make a come back next?
In Windows setting a background image actually changes the background image.
Changing the text actually changes the text.
I can't help but vent, why did they change every property name in WPF?
I started Engine Wars, at http://enginewars.codeplex.com in WPF in 2009, and I have stopped working on it so many times out of frustration, and I cannot change to Windows development now, but this and my controls project are my last WPF projects until things are simple as Windows dev.
Corby