Initially, I have the following code:
<TextBox Text="{Binding LengthUnit, Mode=OneWay}" IsReadOnly="True" Background="{x:Static SystemColors.ControlBrush}" />
I know I can define a style like this:
<Style TargetType="{x:Type TextBox}" x:Key="readOnlyTextBox">
<Setter Property="Background" Value="{x:Static SystemColors.ControlBrush}"></Setter>
<Setter Property="IsReadOnly" Value="True"></Setter>
</Style>
So that I can write:
<TextBox Text="{Binding LengthUnit, Mode=OneWay}" Style="{StaticResource readOnlyTextBox}" />
Because this textbox is readonly, the binding mode cannot be twoway. So, is it possible to make the OneWay binding as the default for my TextBox with this style?
EDIT: I need to change the binding mode to OneWay, because my property is get-only, not because I marked the TextBox readonly. However, I still want to change the default binding mode of the textbox to OneWay if possible.
this is the code I have following your suggestion, but it doesn't work. Did I miss anything?
public class ReadOnlyTextBox : TextBox
{
static ReadOnlyTextBox()
{
TextBox.TextProperty.OverrideMetadata(typeof(ReadOnlyTextBox),
new FrameworkPropertyMetadata() { BindsTwoWayByDefault = false, Journal = true, DefaultUpdateSourceTrigger = UpdateSourceTrigger.Explicit });
}
public ReadOnlyTextBox()
{
base.Background = SystemColors.ControlBrush;
base.IsReadOnly = true;
}
}
Default Data-binding It just defines which is the default binding mode for the control's property. In WPF different controls has different default data-binding modes. For example, TextBlock's Text property has one-way as default binding mode but a TextBox's Text property has a two-way binding mode.
Binding direction Updates the target property or the property whenever either the target property or the source property changes. BindingMode.OneWay. Updates the target property only when the source property changes.
TwoWay: The target property will listen to the source property being changed and will update itself. AND The source property will listen to the target property being changed and will update itself.
Its very easy to do in WPF in comparison of windows Application programming. Two way binding is used when we want to update some controls property when some other related controls property change and when source property change the actual control also updates its property.
Because this textbox is readonly, the binding mode cannot be twoway.
Why not? IsReadOnly will prevent the user from modifying the Text and thereby modifying the property. Just make sure not to modify the Text property in code.
You can prevent the bound property from updating if you subclass TextBox. If you do so, you can override the TextBox.Text Dependency Property metadata.
public class TextBoxEx : TextBox
{
public TextBoxEx() : base() { }
static TextBoxEx()
{
TextBox.TextProperty.OverrideMetadata(typeof(TextBoxEx),
new FrameworkPropertyMetadata() { BindsTwoWayByDefault = false, Journal = true,
DefaultUpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.Explicit });
}
}
For some reasion changing BindsTwoWayByDefault to false doesn't work for me, but you can set DefaultUpdateSourceTrigger to Explicit which means that the bound property won't be updated unless done so by code, effectively making the binding OneWay.
Styles are a way to apply the same set of customizations to one or more properties for UI objects e.g. Background, IsReadOnly etc which are typically dependency properties.
Mode is a property of the Binding object, which is not a UI object.
You can set a style on any element that derives from FrameworkElement or FrameworkContentElement. -- Source (MSDN)
So this is not typically done via XAML/Styling.. my guess is you'd have to write code for it. Although XAML allows you to set nested properties Text.Mode="value", it is error prone (because it assumes that Text has been already set to a binding object). It will result in a binding exception if Text property returns an object that doesn't have a Mode property on it - e.g. if Text="a plain string".
If you absolutely must have this, then you'd need to create your binding programatically. You could use a naming convention for example to see if the backing property has a setter and add a OneWay binding if it doesn't.
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