WPF TextBox: How to change binding mode default to OneWay

bindingbinding-modetextboxwpf

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;            
    }
}

Best Answer

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.

Related Topic