Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to hand over the value of UpdateSourceTrigger to UserControl or update it at runtime?

Tags:

I am facing a problem with UpdateSourceTrigger property. I have a UserControl named LabelWithTextBox, where UpdateSourceTrigger (On Text Property) is not defined (therefore has default value). This should stay like this because of performance (Text should update when Focus is out of the TextBox).

But now I have a case where the UserControl should be used and the update should happen as the user types, therefore I want to set UpdateSourceTrigger to PropertyChanged.

Ideally the best solution would be if the UpdateSourceTrigger property could be inherited. The user uses in his View the UserControl and defines UpdateSourceTrigger = PropertyChanged, this information is handed over to my UserControl and everything works as expected. Does anyone know how I can archive this ?

What other options do I have ? How can I change the UpdateSourceTrigger Property at runtime ?

Here is the relevant UserControl (Code Behind) Code:

public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
    "Text",
    typeof(string),
    typeof(LabelWithTextBox),
    new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

public string Text
{
    get { return (string)this.GetValue(TextProperty); }
    set { this.SetValue(TextProperty, value); }
}

And here is the UserControl (Xaml) Code:

<Grid Grid.Column="1">
            <telerik:RadWatermarkTextBox TextChanged="TextBoxBase_OnTextChanged"
                                         Name="TextBox"
                                         Text="{Binding Text, Mode=TwoWay, ElementName=userControl}"
                                         WatermarkContent="{Binding Placeholder, Mode=TwoWay, ElementName=userControl}"
                                         TextWrapping="{Binding TextWrap, Mode=TwoWay, ElementName=userControl}"
                                         AcceptsReturn="{Binding AcceptsReturn, Mode=TwoWay, ElementName=userControl}"
                                         VerticalScrollBarVisibility="{Binding VerticalScrollBarVisibility, Mode=TwoWay, ElementName=userControl}"
                                         MinLines="{Binding MinLines, Mode=TwoWay, ElementName=userControl}"
                                         MaxLines="{Binding MaxLines, Mode=TwoWay, ElementName=userControl}"
                                         IsReadOnly="{Binding IsReadOnly, ElementName=userControl}"/>
    ....

If add UpdateSourceTrigger = PropertyChanged to Text everything will work as expected. But I do not want that.

Here is for example how someone could use the UserControl in his View. What I am looking for is a way to hand over the value of the UpdateSourceTrigger to my UserControl, but how ?

<controls:LabelWithTextBox
                    Grid.Row="1"
                    Margin="0,5,0,0"
                    Label="Excel Blattname:"
                    SharedSizeGroup="LabelsX"
                    Text="{Binding SheetName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
like image 897
Devid Avatar asked Mar 19 '19 12:03

Devid


1 Answers

UpdateSourceTrigger is a property of the Binding, not the control. In order to pass it to the control, you could pass the entire Binding to an appropriate property.

Your control could expose a TextBinding property:

public partial class LabelWithTextBox : UserControl
{
    public LabelWithTextBox()
    {
        InitializeComponent();
    }

    private BindingBase textBinding;

    public BindingBase TextBinding
    {
        get { return textBinding; }
        set
        {
            textBinding = value;
            TextBox.SetBinding(RadWatermarkTextBox.TextProperty, textBinding);
        }
    }
}

to which you would assign a Binding like

<controls:LabelWithTextBox
  TextBinding="{Binding SheetName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

that is then directly passed to the RadWatermarkTextBox.

The drawback is of course that you can only assign Binding and nothing else.


You may however also use a Text dependency property and inspect its value when the control is loaded. If the value is a Binding, you could use it like this:

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    var binding = GetBindingExpression(TextProperty)?.ParentBinding;

    if (binding != null)
    {
        TextBox.SetBinding(RadWatermarkTextBox.TextProperty, binding);
    }
}
like image 191
Clemens Avatar answered Nov 15 '22 04:11

Clemens