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