有没有办法为已编译的绑定获取 UpdateSourceTrigger=PropertyChanged?
Is there a way to get UpdateSourceTrigger=PropertyChanged for compiled bindings?
我正在开发一个 UWP 应用程序,我意识到 TextBox
控件的默认 UpdateSourceTrigger
模式,即 LostFocus
,在使用编译绑定。
这意味着每当我想为 TextBox
更新绑定时,我都必须使用所有这些重复的样板文件:
<TextBox
Text="{x:Bind ViewModel.Title, Mode=TwoWay}"
TextChanged="TextBox_OnTextChanged"/>
private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
ViewModel.Title = ((TextBox)sender).Text;
}
现在,这还算不错,但是每次使用 TextBox
时都必须记住创建 TextChanged
处理程序,这很烦人且容易出错。
这适用于经典绑定:
<TextBox Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
但是当然,这里会有usinc经典绑定的额外开销(涉及运行时反射等)。
有没有办法获得与 UpdateSourceTrigger=PropertyChanged
相同的行为?我完全可以,比如说,写一个自定义的附加 属性 来设置,只要我可以直接从 XAML 做我需要的一切,不涉及任何代码。
谢谢!
更新: (回应 Nico Zhu - MSFT 的回答)
For my testing, it works well.
它根本不适合我,正如我已经多次说过的,使用 UpdateSourceTrigger
和 x:Bind
只是 不可能 。它不编译,属性 在 XAML 编辑器中显示为红色,只是不存在。如果您说它对您有用,我真的不知道您在哪里尝试。我目前将 17763 作为最低目标,我可以 100% 保证 不会 工作。
Compiled Binding is used with the {x:Bind} syntax as opposed to the {Binding} syntax of Classic Binding.
我很清楚其中的区别,我已经多次提到了这一点,无论是在我的原始问题中(也有代码片段)还是在我的评论中。
It still uses the notifying interfaces (like INotifyPropertyChanged) to watch for changes
正如我所说,我也知道这一点。但是同样,从这个问题来看,这根本不是这里的问题。问题是不是,从视图模型更新到绑定属性,但是来自绑定属性(在本例中为TextBox.Text)到视图模型。
{x:Bind}
is by default OneTime compared to {Binding} which is OneWay. so you need to declare bind Mode OneWay or TwoWay for {x:Bind}.
抱歉,但此时我不得不说,我开始怀疑您是否真的阅读了我最初的问题。我知道这一点,事实上你可以在 both 我的原始代码片段中看到我已经在我的两个绑定中使用了显式 Mode=TwoWay
属性 .
再一次,这根本不是问题的内容。
重申一下:这里的问题是 TextBox.Text
属性 默认为 LostFocus
触发器,而 UpdateSourceTrigger
属性 是 不 可用于已编译的绑定。所以我想知道是否有一种方法可以通过编译绑定在 XAML-only 中实现相同的目的,而不必每次都手动创建一个 TextChanged
处理程序(如果没有,如果您计划最终也将 UpdateSourceTrigger
属性 添加到已编译的绑定中)。
旁注:我并不是有意在这里表达不敬,我希望我们现在已经用我的问题解决了现有的误解。
更新 #2: 原来问题是由 ReSharper 插件引起的,该插件将 UpdateSourceTrigger
属性 标记为编译绑定中的错误。
我在这里打开了一个问题:https://youtrack.jetbrains.com/issue/RSRP-474438
请检查 UpdateSourceTrigger
文档。
默认的 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}" />
doesn't compile at all, as I said the UpdateSourceTrigger
property isn't available at all when using a compiled binding.
对于我的测试,它运行良好。 Compiled Binding 与 {x:Bind}
语法一起使用,而不是 Classic Binding 的 {Binding}
语法。它仍然使用通知接口(如 INotifyPropertyChanged
)来监视更改,但 {x:Bind}
默认是 OneTime,而 {Binding}
是 OneWay。因此您需要为 {x:Bind}
声明绑定 Mode OneWay
或 TwoWay
。
Xaml
<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();
}
}
我正在开发一个 UWP 应用程序,我意识到 TextBox
控件的默认 UpdateSourceTrigger
模式,即 LostFocus
,在使用编译绑定。
这意味着每当我想为 TextBox
更新绑定时,我都必须使用所有这些重复的样板文件:
<TextBox
Text="{x:Bind ViewModel.Title, Mode=TwoWay}"
TextChanged="TextBox_OnTextChanged"/>
private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
ViewModel.Title = ((TextBox)sender).Text;
}
现在,这还算不错,但是每次使用 TextBox
时都必须记住创建 TextChanged
处理程序,这很烦人且容易出错。
这适用于经典绑定:
<TextBox Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
但是当然,这里会有usinc经典绑定的额外开销(涉及运行时反射等)。
有没有办法获得与 UpdateSourceTrigger=PropertyChanged
相同的行为?我完全可以,比如说,写一个自定义的附加 属性 来设置,只要我可以直接从 XAML 做我需要的一切,不涉及任何代码。
谢谢!
更新: (回应 Nico Zhu - MSFT 的回答)
For my testing, it works well.
它根本不适合我,正如我已经多次说过的,使用 UpdateSourceTrigger
和 x:Bind
只是 不可能 。它不编译,属性 在 XAML 编辑器中显示为红色,只是不存在。如果您说它对您有用,我真的不知道您在哪里尝试。我目前将 17763 作为最低目标,我可以 100% 保证 不会 工作。
Compiled Binding is used with the {x:Bind} syntax as opposed to the {Binding} syntax of Classic Binding.
我很清楚其中的区别,我已经多次提到了这一点,无论是在我的原始问题中(也有代码片段)还是在我的评论中。
It still uses the notifying interfaces (like INotifyPropertyChanged) to watch for changes
正如我所说,我也知道这一点。但是同样,从这个问题来看,这根本不是这里的问题。问题是不是,从视图模型更新到绑定属性,但是来自绑定属性(在本例中为TextBox.Text)到视图模型。
{x:Bind}
is by default OneTime compared to {Binding} which is OneWay. so you need to declare bind Mode OneWay or TwoWay for {x:Bind}.
抱歉,但此时我不得不说,我开始怀疑您是否真的阅读了我最初的问题。我知道这一点,事实上你可以在 both 我的原始代码片段中看到我已经在我的两个绑定中使用了显式 Mode=TwoWay
属性 .
再一次,这根本不是问题的内容。
重申一下:这里的问题是 TextBox.Text
属性 默认为 LostFocus
触发器,而 UpdateSourceTrigger
属性 是 不 可用于已编译的绑定。所以我想知道是否有一种方法可以通过编译绑定在 XAML-only 中实现相同的目的,而不必每次都手动创建一个 TextChanged
处理程序(如果没有,如果您计划最终也将 UpdateSourceTrigger
属性 添加到已编译的绑定中)。
旁注:我并不是有意在这里表达不敬,我希望我们现在已经用我的问题解决了现有的误解。
更新 #2: 原来问题是由 ReSharper 插件引起的,该插件将 UpdateSourceTrigger
属性 标记为编译绑定中的错误。
我在这里打开了一个问题:https://youtrack.jetbrains.com/issue/RSRP-474438
请检查 UpdateSourceTrigger
文档。
默认的 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}" />
doesn't compile at all, as I said theUpdateSourceTrigger
property isn't available at all when using a compiled binding.
对于我的测试,它运行良好。 Compiled Binding 与 {x:Bind}
语法一起使用,而不是 Classic Binding 的 {Binding}
语法。它仍然使用通知接口(如 INotifyPropertyChanged
)来监视更改,但 {x:Bind}
默认是 OneTime,而 {Binding}
是 OneWay。因此您需要为 {x:Bind}
声明绑定 Mode OneWay
或 TwoWay
。
Xaml
<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();
}
}