代码之家  ›  专栏  ›  技术社区  ›  Sergio0694

有没有办法为已编译的绑定获取UpdateSourceTrigger=PropertyChanged?

  •  1
  • Sergio0694  · 技术社区  · 6 年前

    我正在开发一个UWP应用程序,我意识到 UpdateSourceTrigger 的模式 TextBox 控制,这是 LostFocus

    这意味着每当我想更新 文本框 ,我不得不用这些重复的样板:

    <TextBox
        Text="{x:Bind ViewModel.Title, Mode=TwoWay}"
        TextChanged="TextBox_OnTextChanged"/>
    
    private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
    {
        ViewModel.Title = ((TextBox)sender).Text;
    }
    

    现在,这还不算太糟,但是必须记住创建 TextChanged 每次 文本框 使用的是恼人的和容易出错的。

    这可以与经典绑定配合使用:

    <TextBox Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    

    当然,这里会有usinc经典绑定的额外开销(包括运行时反射等)。

    UpdateSourceTrigger=PropertyChanged 也?我完全可以,比如说,编写一个自定义的附加属性来进行设置,只要我可以直接从XAML完成我需要的一切,而不需要任何代码。

    谢谢!

    更新:

    对我的测试来说,效果很好。

    更新资源记录器 x:Bind 只是 . 它不编译,属性在XAML编辑器中以红色显示,只是不在那里。我真的不知道你在哪里尝试,如果你说这对你有用的话。我目前的目标是17763作为最低限度,我可以100%保证这是真的 工作。

    编译绑定与{x:Bind}语法一起使用,而不是经典绑定的{Binding}语法。

    我很清楚两者之间的区别,我已经多次提到这个问题,无论是在我最初的问题中(也有代码片段),还是在我的评论中。

    它仍然使用通知接口(如INotifyPropertyChanged)监视更改

    正如我所说,我也意识到这一点。但从这个问题来看,这根本不是问题所在。问题是 使用viewmodel的更新 绑定属性,但是 束缚性质(文本框。文本在这种情况下) 视图模型。

    {x:Bind}

    很抱歉,现在我不得不说,我开始怀疑你是否真的读过我的第一个问题。我知道这一点,事实上你可以从中看到 二者都 我已经使用显式 Mode=TwoWay 属性。

    再一次,这是 问题到底是关于什么的。

    重申:这里的问题是 TextBox.Text 属性默认为 事件 更新资源记录器 可用于已编译的绑定。因此,我想知道是否有一种方法可以实现同样的效果,只使用XAML编译绑定,而不必手动创建 事件 更新资源记录器 属性来创建已编译的绑定)。

    更新#2: 原来这个问题是由ReSharper插件引起的,它正在标记 属性作为已编译绑定中的错误。 我在这里提出了一个问题: https://youtrack.jetbrains.com/issue/RSRP-474438

    0 回复  |  直到 6 年前
        1
  •  0
  •   Nico Zhu    6 年前

    请检查 UpdateSourceTrigger 文档。

    Default . 以及 使用使用绑定的依赖项属性的默认行为。在Windows运行时中,它的计算结果与 PropertyChanged . 如果你用过 Text="{x:Bind ViewModel.Title, Mode=TwoWay}" ,的 职务 TextChanged 甚至处理程序。

    前提是我们需要实施 INotifyPropertyChanged

    public class HostViewModel : INotifyPropertyChanged
    {
        private string nextButtonText;
    
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
    
        public HostViewModel()
        {
            this.NextButtonText = "Next";
        }
    
        public string NextButtonText
        {
            get { return this.nextButtonText; }
            set
            {
                this.nextButtonText = value;
                this.OnPropertyChanged();
            }
        }
    
        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            // Raise the PropertyChanged event, passing the name of the property whose value has changed.
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    Data binding in depth 文件。

    更新

    <TextBox Text="{x:Bind Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 完全不编译,就像我说的 更新资源记录器

    对我的测试来说,效果很好。编译绑定与 {x:Bind} {Binding} 经典绑定的语法。它仍然使用通知接口(如 InotifyProperty已更改 )注意变化但是 默认情况下,与 这是单向的。所以你需要声明绑定 OneWay TwoWay .

    <StackPanel Orientation="Vertical">
        <TextBox Text="{x:Bind Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <TextBlock Text="{x:Bind Title, Mode=OneWay}" /> <!--declare bind mode-->
    </StackPanel>
    

    public event PropertyChangedEventHandler PropertyChanged;
    
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    private string _title;
    public string Title
    {
        get
        {
            return _title;
        }
        set
        {
            _title = value;
            OnPropertyChanged();
        }
    }