2010-04-01 40 views
5

我怎樣纔能有一個對話框編輯一個類的屬性與綁定,並在對話框中有確定 - 取消?編輯對話框,綁定和確定/取消在WPF

我最初的想法是這樣的:

public partial class EditServerDialog : Window { 
    private NewsServer _newsServer; 

    public EditServerDialog(NewsServer newsServer) { 
     InitializeComponent(); 

     this.DataContext = (_newsServer = newsServer).Clone(); 
    } 

    private void ButtonClick(object sender, RoutedEventArgs e) 
    { 
     switch (((Button)e.OriginalSource).Content.ToString()) { 
      case "OK": 
       _newsServer = (NewsServer)this.DataContext; 
       this.Close(); 
       break; 
      case "Cancel": 
       this.Close(); 
       break; 
     } 
    } 
} 

當開關的情況下「OK」,在DataContext包含正確的信息,但最初傳遞NewsServer情況下不會改變。

+0

如果您顯示設置的綁定,它可能會有所幫助。 – 2010-04-01 10:58:11

+0

綁定示例:{Binding NeedAuthentication,UpdateSourceTrigger = LostFocus,Mode = TwoWay}。 綁定是正確的,因爲this.DataContext包含正確的數據。 – ErikTJ 2010-04-01 11:10:20

回答

1

您的NewsServer對象的原始實例未更改,因爲您尚未實際修改它。您的構造函數被調用後,您有以下三個NewsServer引用:

newsServer = original instance 
_newsServer = original instance 
DataContext = clone of original instance 

的OK按鈕被點擊後,引用將如下:

newsServer = original instance 
_newsServer = clone of original instance (possibly modified) 
DataContext = clone of original instance (possibly modified) 

記住,對象是引用類型,在你的作業到_newsServer您只更新其引用,而不是對象本身的值。

爲了允許更新NewsServer對象本身,有兩個選項可以想到,其他選項可能存在,第一個可能是最簡單的。

  • 貫徹執行新的分配到_newsServer領域,而不是調用它的更新方法,並傳入DataContext參考價值的NewsServer對象上void Update(NewsServer source)方法則不用。
  • 公開_newsServer值與公共/內部屬性。您可以通過多種機制來使用它:顯式響應在屬性值更改時引發的事件;綁定到屬性(例如,使其成爲依賴屬性或實現INotifyPropertyChanged);或者只是期望調用者在ShowDialog()方法返回的值爲true的情況下以及何時返回該值。

請注意,如果您在調用方上推回一點邏輯,您的對話類可以更簡單。特別是,一種方法是僅對維護通過屬性暴露給調用者的克隆對象(例如,完全去掉_newsServer字段並僅使用DataContext)。這個對象像以前一樣被綁定到對話框的元素上。調用者只需從ShowDialog()方法的true結果中檢索此實例的參考。

例如:

NewsServer newsServer = ...; 
EditServerDialog editServerDialog = new EditServerDialog(newsServer); 

if (editServerDialog.ShowDialog() == true) 
{ 
    newsServer = editServerDialog.DataContext; 
} 

克隆的目的將簡單地由呼叫者被忽略,如果對話被取消,並且因此ShowDialog()方法返回false。您可以重新使用DataContext屬性(如上所示),或者您可以創建一個僅返回DataContext屬性值(即,使代碼對對話類的公共接口更清晰一些)的不同屬性(例如名爲NewsServer)。

+0

我應該怎麼做,仍然可以取消和/或申請? – ErikTJ 2010-04-05 07:44:32

3

老問題,但我會回答它爲未來的讀者...

您必須在您的綁定上設置UpdateSourceTrigger="Explicit",以便它們不會更新實際源,直到用戶單擊確定。然後在你的OK按鈕處理程序,你可以寫:

BindingExpression be = MyTextBox.GetBindingExpression(TextBox.TextProperty); 
if (be!=null) be.UpdateSource(); 

此外,如果要重置綁定到初始狀態使用

BindingExpression be = MyTextBox.GetBindingExpression(TextBox.TextProperty); 
if (be!=null) be.UpdateTarget(); 

如果你的對話框是複雜的,你可能要遞歸走所有的控件。

0

這是一個老問題,但我最近遇到了這個問題,發現有更好的方法來處理它與.NET 4.5。

首先,標誌着您的綁定UpdateSourceTrigger爲明確:

<CheckBox IsChecked="{Binding MyProperty, UpdateSourceTrigger=Explicit}"/> 

然後,在你確定按鈕單擊事件處理程序使用此:

foreach (var be in BindingOperations.GetSourceUpdatingBindings(this)) 
{ 
    be.UpdateSource(); 
} 

GetSourceUpdatingBindings是在.NET 4.5的新方法。

取消按鈕不需要執行任何操作,因爲綁定已標記爲Explicit,並且只有在調用UpdateSource時纔會「提交」。

相關問題