Pages

Wednesday, 19 November 2008

Custom Control Part 2

In "Custom Control Part 1" we created a raw custom control that does nothing. In this post we'll change the control so it only does "one thing" - stores its original value and when the current value differs it sets the HasChanged property to true.

This needs a couple of private member vars (OldText & Initialised) to hold the state, a new DependencyProperty (HasChangedProperty), a standard CLR property (HasChanged) and some logic added to the TextPropertyChanged event handler.

public class DemoTextBox : TextBox
{
static DemoTextBox()
{
// Create a callback for when the TextProperty changes
PropertyChangedCallback callback = new PropertyChangedCallback(TextPropertyChanged);

// Override the TextProperty metadata in order to link up the callback routine
TextProperty.OverrideMetadata(
typeof(DemoTextBox),
new FrameworkPropertyMetadata(callback));
}
static void TextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
// Cast the Sender to an object of this class
DemoTextBox textBox = (DemoTextBox)sender;
 

// Store the OldText value when this event is
// fired for the first time
 
if (!textBox.Initialised)
{
textBox.Initialised = true;
textBox.OldText = textBox.Text;
}

// Set the HasChangedProperty to indicate whether the text has changed

textBox.SetValue(HasChangedProperty, (textBox.OldText != textBox.Text));

 
}

 
private bool Initialised = false;
private string OldText = "";
 
// The new DependencyProperty
 
static readonly DependencyProperty HasChangedProperty = DependencyProperty.Register(
"HasChanged",
typeof(bool),
typeof(DemoTextBox)
);
 
// The new CLR Property
 
public bool HasChanged
{
get { return (bool)GetValue(HasChangedProperty); }
}

}

In the Generic.xaml we'll add a Trigger to turn the textbox background Red when the Text value has changed.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DepProp">
<Style TargetType="{x:Type local:DemoTextBox}">
<Style.Triggers>

<Trigger Property="HasChanged" Value="true">
<Setter Property="Background" Value="Red"/>
</Trigger>

</Style.Triggers>
</Style>
</ResourceDictionary>

No comments: