如何将UpdateSourceTrigger的值移交给UserControl或在运行时更新它?

时间:2019-03-19 12:44:07

标签: c# wpf xaml user-controls telerik

我面临UpdateSourceTrigger属性的问题。我有一个名为LabelWithTextBox的UserControl,其中未定义UpdateSourceTrigger(文本属性)(因此具有默认值)。由于性能,它应该保持这样(当Focus不在TextBox中时,Text应该更新)。

但是现在我有一种情况,应该使用UserControl并根据用户类型进行更新,因此我想将UpdateSourceTrigger设置为PropertyChanged。

理想情况下,最佳解决方案是可以继承UpdateSourceTrigger属性。用户在其视图中使用UserControl并定义UpdateSourceTrigger = PropertyChanged,此信息将移交给我的UserControl,并且一切正常。有谁知道我该怎么存档?

我还有哪些其他选择?如何在运行时更改UpdateSourceTrigger属性?

这是相关的UserControl(后面的代码)代码:

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

这是UserControl(Xaml)代码:

<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}"/>
    ....

如果将UpdateSourceTrigger = PropertyChanged添加到Text,一切将按预期工作。但是我不想要那个。

例如,这是某人如何在其视图中使用UserControl的方法。我正在寻找的是一种将UpdateSourceTrigger的值移交给我的UserControl的方法,但是如何?

<controls:LabelWithTextBox
                    Grid.Row="1"
                    Margin="0,5,0,0"
                    Label="Excel Blattname:"
                    SharedSizeGroup="LabelsX"
                    Text="{Binding SheetName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

2 个答案:

答案 0 :(得分:2)

对我来说,你还想实现什么目标还不够清楚

您可以在代码中(而不是在XAML中)将Binding设置为RadWatermarkTextBox

编辑:

现在我明白了你想要什么:)

将其添加到用户控件中:

public bool UpdateOnPropChanged
{
    get
    {
        return _updateOnPropChanged;
    }
    set
    {
        _updateOnPropChanged = value;
        this.TextBox.SetBinding(TextBox.TextProperty, new Binding("Text") { RelativeSource=new RelativeSource(RelativeSourceMode.FindAncestor) { AncestorType=typeof(LabelWithTextBox) }, UpdateSourceTrigger = _updateOnPropChanged ? UpdateSourceTrigger.PropertyChanged : UpdateSourceTrigger.LostFocus });
    }
}
private bool _updateOnPropChanged;

您可以这样使用:

<controls:LabelWithTextBox UpdateOnPropChanged="false"/>

答案 1 :(得分:2)

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