简体   繁体   English

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

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

I am facing a problem with UpdateSourceTrigger property. 我遇到了UpdateSourceTrigger属性的问题。 I have a UserControl named LabelWithTextBox, where UpdateSourceTrigger (On Text Property) is not defined (therefore has default value). 我有一个名为LabelWithTextBox的UserControl,其中未定义UpdateSourceTrigger(On Text Property)(因此具有默认值)。 This should stay like this because of performance (Text should update when Focus is out of the TextBox). 由于性能原因,这应该保持这样(当Focus不在TextBox中时,Text应该更新)。

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. 但是现在我有一个应该使用UserControl的情况,并且更新应该在用户输入时发生,因此我想将UpdateSourceTrigger设置为PropertyChanged。

Ideally the best solution would be if the UpdateSourceTrigger property could be inherited. 理想情况下,最好的解决方案是如果可以继承UpdateSourceTrigger属性。 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. 用户在他的View中使用UserControl并定义UpdateSourceTrigger = PropertyChanged,这些信息被移交给我的UserControl,一切都按预期工作。 Does anyone know how I can archive this ? 有谁知道如何归档这个?

What other options do I have ? 我还有其他选择吗? How can I change the UpdateSourceTrigger Property at runtime ? 如何在运行时更改UpdateSourceTrigger属性?

Here is the relevant UserControl (Code Behind) Code: 这是相关的UserControl(Code Behind)代码:

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

If add UpdateSourceTrigger = PropertyChanged to Text everything will work as expected. 如果将UpdateSourceTrigger = PropertyChanged添加到Text,一切都将按预期工作。 But I do not want that. 但我不希望这样。

Here is for example how someone could use the UserControl in his View. 例如,有人可以在他的View中使用UserControl。 What I am looking for is a way to hand over the value of the UpdateSourceTrigger to my UserControl, but how ? 我正在寻找的是一种将UpdateSourceTrigger的值交给我的UserControl的方法,但是如何?

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

It's not clear enough for me what do you want to achieve 对我来说,你想要达到什么目标还不够明确

You can set Binding to RadWatermarkTextBox in code, not in XAML. 您可以在代码中设置Binding到RadWatermarkTextBox ,而不是在XAML中。

EDIT: 编辑:

Now I see what you want :) 现在我看到你想要的:)

Add it to your user control: 将其添加到您的用户控件:

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;

And you can use it so: 你可以使用它:

<controls:LabelWithTextBox UpdateOnPropChanged="false"/>

UpdateSourceTrigger is a property of the Binding, not the control. UpdateSourceTrigger是Binding的属性,而不是控件。 In order to pass it to the control, you could pass the entire Binding to an appropriate property. 为了将它传递给控件,​​您可以将整个Binding传递给适当的属性。

Your control could expose a TextBinding property: 您的控件可能会公开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);
        }
    }
}

to which you would assign a Binding like 你要指定一个Binding之类的

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

that is then directly passed to the RadWatermarkTextBox. 然后直接传递给RadWatermarkTextBox。

The drawback is of course that you can only assign Binding and nothing else. 缺点当然是你只能分配Binding而不能分配其他内容。


You may however also use a Text dependency property and inspect its value when the control is loaded. 但是,您也可以使用Text依赖项属性并在加载控件时检查其值。 If the value is a Binding, you could use it like this: 如果值是Binding,您可以像这样使用它:

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

    var binding = GetBindingExpression(TextProperty)?.ParentBinding;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM