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

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

我遇到了 UpdateSourceTrigger 属性 的问题。我有一个名为 LabelWithTextBox 的用户控件,其中未定义 UpdateSourceTrigger (On Text 属性)(因此具有默认值)。由于性能原因,这应该保持这种状态(当焦点不在 TextBox 中时,文本应该更新)。

但现在我有一个情况应该使用 UserControl 并且更新应该在用户键入时发生,因此我想将 UpdateSourceTrigger 设置为 属性Changed。

理想情况下,最好的解决方案是可以继承 UpdateSourceTrigger 属性。用户在他的 View 中使用 UserControl 并定义 UpdateSourceTrigger = 属性Changed,此信息被移交给我的 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); }
}

这是用户控件 (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 = 属性更改为文本,一切都会按预期工作。但我不想那样。

下面是某人如何在他的视图中使用 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}" />

我不太清楚你想达到什么目的

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

编辑:

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

将其添加到您的用户控件:

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

UpdateSourceTrigger是一个属性的Binding,不是control。为了将其传递给控件,​​您可以将整个 Binding 传递给适当的 属性.

您的控件可以公开 TextBinding 属性:

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

您将为其分配绑定,例如

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

然后直接传递给 RadWatermarkTextBox。

缺点当然是只能赋值Binding,不能赋值其他。


但是,您也可以使用 Text 依赖项 属性 并在加载控件时检查其值。如果值是一个绑定,你可以这样使用它:

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

    var binding = GetBindingExpression(TextProperty)?.ParentBinding;

    if (binding != null)
    {
        TextBox.SetBinding(RadWatermarkTextBox.TextProperty, binding);
    }
}