2010-04-01 13 views
5

Bir sınıfın özelliklerini bağlayıcı ile düzenlemek için bir iletişim kutusu nasıl olabilir ve iletişim kutusunda Tamam İptal var mı?Düzenleme, ciltleme ve Tamam/İptal ile WPF içinde

Benim ilk fikir olduğunu bu:

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; 
     } 
    } 
} 

anahtarı, vaka "Tamam", DataContext doğru bilgileri içerir, ancak orijinal olarak geçti NewsServer örneği değişmez

.

+0

Bağlama kurulumunu gösterirseniz yardımcı olabilir. –

+0

Ciltleme örneği: {Binding NeedAuthentication, UpdateSourceTrigger = LostFocus, Mode = TwoWay}. Bu.DataContext doğru verileri içerdiğinden, bağlayıcı doğrudur. – ErikTJ

cevap

1

NewsServer nesnesinin orijinal örneği değiştirilmediğinden değiştirilmemiştir.

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

nesneler referans tipleri Ödeviniz, olduğunu unutmayın: Tamam düğmesi aşağıdaki gibi referanslar olacak tıklandığında sonra

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

: En yapıcısı denir sonra aşağıdaki üç NewsServer referanslara sahip _newsServer için sadece referansını güncelliyorsunuz, nesnenin kendisinin değerini değil.

NewsServer nesnesinin güncellenmesine izin vermek için, akla gelen iki seçenek vardır, diğer seçenekler muhtemelen var, ilki muhtemelen en basit olanıdır.

  • yerine üzerinde güncelleme yöntemini çağırın ve DataContext referans değer geçirir _newsServer alanına yeni atama işleminin ardından yerine NewsServer nesne üzerinde bir void Update(NewsServer source) yöntemi uygulamak.
  • _newsServer değerini bir ortak/dahili özellik ile ortaya çıkarın. Bunu çeşitli mekanizmalarla kullanabilirsiniz: özellik değeri değiştiğinde ortaya çıkan bir olaya açıkça yanıt verin; özelliğe bağlamak (örneğin, bir bağımlılık özelliği yapmak veya INotifyPropertyChanged uygulamak); veya ShowDialog() yönteminin true değeri ile döndüğünde, arayanın değeri almasını beklemeniz yeterlidir.

Arayanın biraz mantığını geri yüklerseniz, iletişim sınıfınızın daha basit olabileceğini unutmayın. Özellikle, bir yaklaşım sadece klonlanmış nesneyi bir özellik aracılığıyla arayan kişiye maruz bırakılır (örn. _newsServer alanından kurtulmak ve sadece DataContext kullanın). Bu nesne, diyaloğun elemanlarına önceden olduğu gibi bağlanacaktır. Arayan kişi bu örneğin referansını, ShowDialog() yönteminden true sonucundan alır. Örneğin

: klonlanmış nesne iletişim yapılması durumunda, sadece bir arayan tarafından göz ardı ve böylece ShowDialog() yöntem false döndürür olur

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

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

. DataContext özelliğini yukarıda gösterildiği gibi yeniden kullanabilirsiniz veya DataContext özellik değerini döndüren farklı bir özellik (örneğin, NewsServer olarak adlandırılır) oluşturabilir (kodun iletişim sınıfının genel arabirimiyle ilgili daha net olması için).

+0

Bunu nasıl yapmalıyım ve hala iptal edebilir ve/veya uygulayabilir miyim? – ErikTJ

3

Eski soru ama gelecekteki okuyucular için cevaplayacağım ...

Bağlamalarınıza UpdateSourceTrigger="Explicit"'u ayarlamalısınız, böylece kullanıcılar OK (Tamam) 'ı tıklayana kadar güncel kaynağı güncelleştirmeyeceklerdir. Sonra Tamam düğmesi işleyicisi üzerine yazabilirsiniz:

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

Ayrıca devlet kullanacağım

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

alınmalarını bağlamaları sıfırlamak istiyorsanız iletişim özyinelemeli denetimlerinin tüm yürümek isteyebilirsiniz karmaşık olursa .

0

Bu eski bir sorudur, ancak kısa bir süre önce buna rastladım ve .NET 4.5 ile başa çıkmanın daha iyi bir yolunu buldum.

Birincisi, Açık olarak bağlantıları UpdateSourceTrigger işaretlemek:

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

Ardından, Tamam düğmesini tıklatın olay işleyicisi bu kullanın:

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

GetSourceUpdatingBindings .NET 4.5 yeni bir yöntemdir.

İptal düğmesinin herhangi bir şey yapması gerekmez, çünkü bağlamalar Açık olarak işaretlenmiş ve yalnızca UpdateSource çağrıldığında "işlenen" olacaktır.

İlgili konular