2

在 WPF 中使用数据绑定时,如果将Mode属性设置为TwoWay,则可以通过设置属性来控制源属性更新的时刻UpdateSourceTrigger。对于目标 -> 源更新流,这种情况是可能的。但是如何控制源 -> 目标更新流的相同内容?我找不到同等的财产。

例如,假设我的窗口上有两个文本框,我想绑定两个文本框的 Text 属性。XAML 可能如下所示:

        <TextBox
            Name="txt1"
            Text="{Binding ElementName=txt2, Path=Text, Mode=TwoWay,
            UpdateSourceTrigger=LostFocus}"
            />
        <TextBox
            Name="txt2"
            />

当用户在 TextBox 中输入文本时txt1, Textbox 的Text属性txt2将随着Text属性的变化而更新,就像我在 上实现了 TextChanged 事件一样txt1

但是,当用户在 TextBox 中输入文本时,txt2TextBox 的Text属性txt1将在txt2TextBox 失去焦点后更新,因为UpdateSourceTrigger属性设置为LostFocus,就像我实现了 LostFocus 事件一样。

在源属性控制失去焦点后,WPF 数据绑定中是否有可能更新目标属性?在我们的示例中:应该对上面的 XAML 代码做些什么,所以TextBoxText的属性txt2只会在txt1TextBox 失去焦点后更新,而不是在其 Text 属性更改后更新?

谢谢!

4

2 回答 2

1

UpdateSourceTrigger机制与 WPF 控件的隐式性质相关联。通过这种方式,您可以决定何时更新源。另一方面,源可以是 a UIElement,但也可以是另一个对象。实际上,作为绑定源的对象可以通过实现来通知其对绑定的更改INotifyPropertyChanged。使用此接口,对象会在每次属性更改时通知其更改。

因此,如果您想要一种“UpdateTargetTrigger”,您应该在控件中实现它。例如,您可以通过以下方式扩展 TextBox 控件:

public class ExtTextBox : TextBox, INotifyPropertyChanged
{
    private event PropertyChangedEventHandler propertyChanged;
    private string textOnLostFocus;

    public event PropertyChangedEventHandler PropertyChanged
    {
        add
        {
            propertyChanged += value;
        }
        remove
        {
            propertyChanged -= value;
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected override void OnLostFocus(RoutedEventArgs e)
    {
        base.OnLostFocus(e);
        SetTextOnLostFocus(Text, false);
    }

    private void SetTextOnLostFocus(string text, bool updateText)
    {
        if (StringComparer.Ordinal.Compare(textOnLostFocus, text) != 0)
        {
            textOnLostFocus = text;
            if (updateText)
            {
                Text = text;
            }

            OnPropertyChanged("TextOnLostFocus");
        }
    }

    public string TextOnLostFocus
    {
        get
        {
            return textOnLostFocus;
        }
        set
        {
            SetTextOnLostFocus(Text, true);
        }
    }
}

我使用 TextOnLostFocus 作为支持,仅在 LostFocus 事件上通知其更改。因此,您的 XAML 将是:

<TextBox Name="txt1" Text="{Binding ElementName=txt2, Path=TextOnLostFocus, Mode=TwoWay,
                                    UpdateSourceTrigger=LostFocus}" Margin="3" />
<local:ExtTextBox x:Name="txt2" Margin="3" />

我希望它可以帮助你。

于 2015-03-13T10:14:51.870 回答
1

为什么不定义两个绑定?这对我有用:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBox Name="txt1" Margin="4" 
                 Text="{Binding ElementName=txt2, Path=Text, Mode=OneWay}" />
        <TextBox Name="txt2" Margin="4" 
                 Text="{Binding ElementName=txt1, Path=Text, Mode=OneWay}" />
    </StackPanel>
</Window>
于 2015-03-12T22:49:17.700 回答