2014-10-02 47 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; 
       } 
      }));