I am using the Infragistics XamDateTimeEditor control and I want to add a dependency property to it to allow the developer to choose to have all the text selected when the control gets focus. I have created a style that is used to set the behavior I want but I want the developer to decide if the behavior should be executed based on a boolean dependency property. I am not sure how that is done.
A dependency property can reference a value through data binding. Data binding works through a specific markup extension syntax in XAML, or the Binding object in code. With data binding, determination of the final property value is deferred until run time, at which time the value is obtained from a data source.
The XAML processor sets the value of the dependency property using the SetValue method: Setters not run on Dependency Properties? If you want to do something whenever the property is being set to a new value, you should register a callback: public static DependencyProperty TestProperty = DependencyProperty.
Attached properties allows container to create a property which can be used by any child UI elements whereas dependency property is associated with that particular elements and can help in notification of changes and reacting to that changes.
Why We Need Dependency Properties. Basically, Dependency Properties offer a lot of functionalities that you won't get by using a CLR property. CLR properties can directly read/write from the private member of a class by using getter and setter. In contrast, dependency properties are not stored in local object.
I assume you inherited from XamDateTimeEditor for this.
If you can write the code referencing a "standard" (clr) property, then you are good to go:
remove your backing field and replace the implementation of the standard property so that it accesses the DependencyProperty instead of the backing field.
public class MyXamDateTimeEditor : XamDateTimeEditor
{
public static readonly DependencyProperty IsSelectOnFocusEnabledProperty =
DependencyProperty.Register("IsSelectOnFocusEnabled", typeof(bool),
typeof(MyXamDateTimeEditor), new UIPropertyMetadata(false));
public boolIsSelectOnFocusEnabled
{
get
{
return (bool)GetValue(IsSelectOnFocusEnabledProperty);
}
set
{
SetValue(IsSelectOnFocusEnabledProperty, value);
}
}
}
Then, when you access IsSelectOnFocusEnabled in your code it will return the current value of the Dependency Property.
You can also set it up to receive notification whenever the property changes, but I don't see why you would in your case.
There is also another option for this trick, which uses no inheritance and an attached property if you'd like.
UPDATE:
OK, since it was requested, here's a way to achieve that for any textbox. It should be easy to translate to whatever event you use to carry that out on another type of control.
public class TextBoxBehaviors
{
public static bool GetIsSelectOnFocusEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsSelectOnFocusEnabledProperty);
}
public static void SetIsSelectOnFocusEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsSelectOnFocusEnabledProperty, value);
}
public static readonly DependencyProperty IsSelectOnFocusEnabledProperty =
DependencyProperty.RegisterAttached("IsSelectOnFocusEnabled", typeof(bool),
typeof(TextBoxBehaviors),
new UIPropertyMetadata(false, new PropertyChangedCallback(OnSelectOnFocusChange)));
private static void OnSelectOnFocusChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TextBox)
{
var tb = d as TextBox;
if ((bool)e.NewValue)
{
tb.GotFocus += new RoutedEventHandler(tb_GotFocus);
}
else
{
tb.GotFocus -= new RoutedEventHandler(tb_GotFocus);
}
}
}
static void tb_GotFocus(object sender, RoutedEventArgs e)
{
var tb = sender as TextBox;
tb.SelectAll();
}
}
The way you use it is as follows, for example:
<Window x:Class="WpfApplication2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Text="No Select All" x:Name="TextBox1"/>
<CheckBox Content="Auto Select"
Grid.Column="1"
IsChecked="{Binding Path=(local:TextBoxBehaviors.IsSelectOnFocusEnabled), ElementName=TextBox1, Mode=TwoWay}" />
<TextBox Grid.Row="1" Text="djkhfskhfkdssdkj"
local:TextBoxBehaviors.IsSelectOnFocusEnabled="true" />
</Grid>
</Window>
This shows you how to set up the property to activate the behavior, and how to bind it to something else if need be. Note that this specific example is not perfect (if you tab through it works, if you click inside the control, the textbox has internal logic that actually deselects the text, but that's just an example on how to attach behaviors to controls through attached properties).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With