WPF mvvm绑定,获取/设置值:阻止更新值的问题
本文关键字:更新 问题 设置 绑定 mvvm 获取 WPF | 更新日期: 2023-09-27 18:25:15
我在WPF mvvm环境中工作。
我有一些从cs文件到xaml的绑定变量和数据。
一个不同于其他选项卡:它是我的选项卡集合中所选选项卡的索引。当用户打开了多个选项卡,并且有MOD要保存时,我会向他显示一个对话框。如果他点击"ok",他将继续更改选项卡,如果他单击"cancel",则选项卡必须保持不变。
这是我的代码:
private int p_SelectedDocumentIndex;
public int SelectedDocumentIndex{ get { return p_SelectedDocumentIndex; }
set {
if (tabsCollection.Count() > 1 && CanSave() == true)
{
if (dm.ShowMessage1(ServiceContainer.GetService<DevExpress.Mvvm.IDialogService>("confirmYesNo")))
{
p_SelectedDocumentIndex = value;
base.RaisePropertiesChanged("SelectedDocumentIndex");
}
//else {
// CODE FOR NOT CHANGE THE VALUE
//}
}
else {
p_SelectedDocumentIndex = value;
base.RaisePropertiesChanged("SelectedDocumentIndex");
}
}
}
所以,问题是:我怎么能不在"集合"部分应用更改呢?
这是最简单的方法,但是,如果这种方法不正确,我该怎么办?
以前的失败尝试:
1)
p_SelectedDocumentIndex = p_SelectedDocumentIndex
base.RaisePropertiesChanged("SelectedDocumentIndex");
2)
base.RaisePropertiesChanged("SelectedDocumentIndex");
3)
nothing in the else branch
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => SelectedDocumentIndex= p_SelectedDocumentIndex ), DispatcherPriority.Send);
此调用安排将UI状态恢复到操作启动之前的状态
我解决了它。我从这里得到了解决方案:
http://blog.alner.net/archive/2010/04/25/cancelling-selection-change-in-a-bound-wpf-combo-box.aspx
public int SelectedDocumentIndex{ get { return p_SelectedDocumentIndex; }
set {
// Store the current value so that we can
// change it back if needed.
var origValue = p_SelectedDocumentIndex;
// If the value hasn't changed, don't do anything.
if (value == p_SelectedDocumentIndex)
return;
// Note that we actually change the value for now.
// This is necessary because WPF seems to query the
// value after the change. The combo box
// likes to know that the value did change.
p_SelectedDocumentIndex = value;
if (tabsCollection.Count() > 1 && CanSave() == true)
{
if (!dm.ShowMessage1(ServiceContainer.GetService<DevExpress.Mvvm.IDialogService>("confirmYesNo")))
{
Debug.WriteLine("Selection Cancelled.");
// change the value back, but do so after the
// UI has finished it's current context operation.
Application.Current.Dispatcher.BeginInvoke(
new Action(() =>
{
Debug.WriteLine("Dispatcher BeginInvoke " + "Setting CurrentPersonCancellable.");
// Do this against the underlying value so
// that we don't invoke the cancellation question again.
p_SelectedDocumentIndex = origValue;
DocumentPanel p = tabsCollection.ElementAt(p_SelectedDocumentIndex);
p.IsActive = true;
base.RaisePropertiesChanged("SelectedDocumentIndex");
}),
System.Windows.Threading.DispatcherPriority.ContextIdle,
null
);
// Exit early.
return;
}
}
// Normal path. Selection applied.
// Raise PropertyChanged on the field.
Debug.WriteLine("Selection applied.");
base.RaisePropertiesChanged("SelectedDocumentIndex");
}
}
如果您的VM类是从DependencyObject
派生的,那么您可以通过强制回调将属性更改为DependecyProperty
,该回调启用"撤消",如下所示:
public int SelectedDocumentIndex
{
get { return (int)GetValue(SelectedDocumentIndexProperty); }
set { SetValue(SelectedDocumentIndexProperty, value); }
}
public static readonly DependencyProperty SelectedDocumentIndexProperty =
DependencyProperty.Register("SelectedDocumentIndex", typeof(int), typeof(MyViewModel), new PropertyMetadata(0,
(d, e) =>
{
//Callback after value is changed
var vm = (MyViewModel)d;
var val = (int)e.NewValue;
}, (d, v) =>
{
//Coerce before value is changed
var vm = (MyViewModel)d;
var val = (int)v;
if (vm.tabsCollection.Count() > 1 && vm.CanSave() == true)
{
if (vm.dm.ShowMessage1(ServiceContainer.GetService<DevExpress.Mvvm.IDialogService>("confirmYesNo")))
{
//no coerce is needed
return v;
}
else
{
//should coerce to the previous value
return VM.SelectedDocumentIndex;
}
}
else
{
//no coerce is needed
return v;
}
}));