2014-10-02 76 views
1

我正在WPF mvvm环境中工作。WPF mvvm绑定,获取/设置值:防止更新值问题

我有一些绑定的变量和数据从cs文件到xaml。

一个不同于其他人:它是我的tabsCollection中选定选项卡的索引。当用户有多个选项卡打开并且有MODS保存时,我会向他展示一个对话框。如果他碰到“ok”,他会继续更改标签,如果他点击“取消”,标签必须保持不变。

这是我的代码:

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 
+0

以下是什么回报? dm.ShowMessage1(ServiceContainer.GetService (“confirmYesNo”)) – Godspark 2014-10-02 08:02:34

+0

我在问题中说过...它是一个索引。当前活动选项卡的索引。当我改变它时,我会向用户显示一个对话框。如果他点击“取消”,我不想更改值,所以我需要删除新值并保留前一个值。 – 2014-10-02 08:03:52

+1

我认为ShowMessage通常会返回一个dialogResult,并且您必须检查DialogResult是否正确或取消,然后基于dialogresult,您将设置您的私有变量。否则,你不会设置它,以保留'oldvalue' – Krishna 2014-10-02 08:37:01

回答

0

之前,我解决了它。我把从这里的解决方案:

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"); 
     } 
    } 
1
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => SelectedDocumentIndex= p_SelectedDocumentIndex), DispatcherPriority.Send); 

这个调用安排以恢复用户界面状态,这是在操作开始

0

如果你的虚拟机类是从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; 
       } 
      }));