Jam*_*nen 4 c# wpf binding mvvm
我有一个Window代表数据编辑器的WPF .所述DataContext的Window是可观察到的对象的(实现INotifyPropertyChanged).
可观察到的对象的属性中的每一个结合到一个适当的插件在Window(TextBox用于数字类型,CheckBox为bool等).
我不想让"确定"和"取消"按钮来保持更改的属性; 我希望当窗口小部件失去焦点时,底层数据将持久保存到可观察对象.
为此,我已经处理了小部件的事件PreviewLostKeyboardFocus和LostFocus事件.我的undo框架需要一个代表当前状态的observable对象的副本,以及一个新状态的副本.该PreviewLostKeyboardFocus事件使对象的副本,以及LostFocus活动实际执行保存到数据库中.
但我的问题是这样的:绑定场上不会实际更新底层观察的对象,直到后的LostFocus运行事件.实际效果是将文本TextBox从"A"更改为"B"将使字段中的数据保持为"A".将其从"A"更改为"B"到"C"将持续"B".
我在事件处理程序和底层对象的setter中放置了断点.果然,PreviewLostKeyboardFocus首先运行,然后运行,LostFocus最后是可观察对象的setter.
我想让它尽可能通用,所以虽然我可以告诉可观察对象使用它更新自己的属性KeyboardFocusChangedEventArgs,但我需要为每个字段分别设置事件处理程序,并且可能会有很多.
有没有什么办法让Binding运行之间的PreviewLostKeyboardFocus和LostFocus事件?
XAML:
<TextBox Text="{Binding ObjectProperty, StringFormat='{}{0:F5}'}" LostFocus="PersistentTextBox_LostFocus" PreviewLostKeyboardFocus="PersistentTextBox_PreviewLostKeyboardFocus" />
Run Code Online (Sandbox Code Playgroud)
代码背后的事件处理程序:
private void PersistentTextBox_LostFocus(object sender, RoutedEventArgs e) {
this.ObservableObject.PersistChanges(this.tempObservableObject);
}
private void PersistentTextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
this.tempObservableObject = this.ObservableObject;
}
Run Code Online (Sandbox Code Playgroud)
ObservableObject class(setter):
public class ObservableObject : INotifyPropertyChanged {
...
public Single ObjectProperty {
get {
return this._objectProperty;
}
set {
this._objectProperty = value;
RaisePropertyChanged("ObjectProperty");
}
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
如果我正确理解了您的问题,这可能是因为默认情况下TextBox更新Source时焦点丢失.
解决这个问题的一种方法是设置TextBox UpdateSourceTrigger为PropertyChanged
<TextBox Text="{Binding ObjectProperty, UpdateSourceTrigger=PropertyChanged, StringFormat='{}{0:F5}'}"
Run Code Online (Sandbox Code Playgroud)
这将允许在更改后立即更新基础可观察对象TextBox,然后您可以在窗口小部件丢失焦点事件中保留更改
或者您可以在LostFocus处理程序中设置UpdateSourceTriggerto Explicit并更新Source.
<TextBox Text="{Binding ObjectProperty, UpdateSourceTrigger=Explicit, StringFormat='{}{0:F5}'}"
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
(sender as TextBox).GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6036 次 |
| 最近记录: |