2009-02-13 15 views
8

WPF uygulamamı, kullanıcıların kaydedilmemiş değişikliklerini iptal etmelerini veya bir TreeView kullanarak gezinirken iptal etmelerini istemeye çalışıyorum. How do I properly handle a PreviewMouseDown event with a MessageBox confirmation? WPF: MessageBox Break PreviewMouseDown mı?

How can I cancel a user’s WPF TreeView click?

    • ben bir hata buldum. MessageBox PreviewMouseDown ile güzel oynamıyor. Bir MessageBox'ın gösterilmesi durumunda e.Handled'in nasıl ayarlandığına bakılmaksızın bir tıklamanın "ele alınması" gibi görünüyor. Bu XAML için

      ...
      <TreeView Name="TreeViewThings" 
          ... 
          PreviewMouseDown="TreeViewThings_PreviewMouseDown" 
          TreeViewItem.Expanded="TreeViewThings_Expanded" 
          TreeViewItem.Selected="TreeViewThings_Selected" > 
      

      ... bu alternatif yöntemler karşılaştırmak ...

       
      Sub TreeViewNodes_PreviewMouseDown(...) 
          e.Handled = False 
      End Sub 
      
      Sub TreeViewNodes_PreviewMouseDown(...) 
          MessageBox.Show("Test", "Test", MessageBoxButton.OK) 
          e.Handled = False 
      End Sub 
      

      Bu iki yöntem farklı davranır. MessageBox olmadan, TreeViewNodes_Selected() veya TreeViewThings_Expanded() yürütülür. MessageBox ile yapmazlar.

      Bu bir hata mı, yoksa anlaması gereken bir şey mi var?

  • cevap

    2

    Tam olarak aynı sorunu yaşıyorum ve MessageBox'ın işleri batırdığını düşünüyorum. Dürüst olmak gerekirse, WPF'ye geçmeden önce Windows Forms ile çalışırken MessageBox ile başka sorunlar yaşadım. Belki de bir özellik haline gelen bir asırlık hata (Microsoft ile olduğu gibi).

    Her halükarda size sunabileceğim tek çözüm benim için çalışmış olan çözümdür. Bir ListBox ile çalışmak için benzer bir durumun oluşmasıyla ilgili problemlerim vardı - eğer formdaki verilerde değişiklik olsaydı, ListBox'un seçimi değiştiğinde (yeni maddeye tıklayarak veya "Yukarı" veya "Aşağı" tuşlarını kullanarak), MessageBox'ta kaydetmeyi, atmayı veya iptal etmeyi seçtim.

    Doğal olarak, ListBox'un MouseDown veya PreviewMouseDown olaylarını işlemenin doğrudan yaklaşımını kullanarak MessageBox ile iyi çalışmadı. İşte işe yaradı.

    <ListBox.ItemTemplate> 
        <DataTemplate> 
         <TextBlock Text="{Binding Path=NAME}" KeyDown="checkForChanges" MouseDown="checkForChanges"/> 
        </DataTemplate> 
    </ListBox.ItemTemplate> 
    

    Not I için KeyDown ve MouseDown olayı işleyicileri taşındı ne kadar:

    (Ben hemen hemen aynı olması sizi bekliyorum) benim ListBox öğeleri görüntülemek için bir veri şablonu var Bunun yerine TextBlock denetimi. Her zaman ItemsSource sahiptir ListBox seçili öğeye, değişiklikler (ı don bir DataTable ile ilişkili zaman Modifiye olarak benim DataRow işaretler nasıl Cilt çok tuhaf bir yan not olarak

    // The KeyDown handler 
    private void checkForChanges(object sender, KeyEventArgs e) { 
        e.Handled = checkForChanges(); 
    } 
    
    // Method that checks if there are changes to be saved or discard or cancel 
    private bool checkForChanges() { 
        if (Data.HasChanges()) { 
         MessageBoxResult answer = MessageBox.Show("There are unsaved changes. Would you like to save changes now?", "WARNING", MessageBoxButton.YesNoCancel, MessageBoxImage.Question); 
         if (answer == MessageBoxResult.Yes) { 
          Data.AcceptDataChanges(); 
         } else if (answer == MessageBoxResult.Cancel) { 
          return true; 
         } 
         return false; 
        } 
        return false; 
    } 
    
    // The MouseDown handler 
    private void checkForChanges(object sender, MouseButtonEventArgs e) { 
        e.Handled = checkForChanges(); 
    } 
    

    : Ben aynı kodu-arkasında tuttu DataTables/Sets kullanıp kullanmadığınızı bilmiyoruz. Seçim zaten değiştikten sonra o savaş için ben herhangi işlenmeyen değişiklikleri atmak (Ben bundan önce meydana olay MouseDown gereken her şeyi idare çünkü):

    <ListBox IsSynchronizedWithCurrentItem="True" [...] SelectionChanged="clearChanges"> ... </ListBox> 
    

    Ve işleyicisi için kod arkasında:

    private void clearChanges(object sender, SelectionChangedEventArgs e) { 
        Data.cancelChanges(); 
    } 
    
    0

    Elde ettiğim şey budur. Çalışır, ama daha az arzu edilir ...

    Sub TreeViewNodes_PreviewMouseDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) 
        If UnsavedChangesExist() Then 
         MessageBox.Show("You have unsaved changes.", "Unsaved Changes", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK) 
         e.Handled = True 
        End If 
    End Sub 
    

    Bu

    , "Tamam", el ile ("Kaydet" düğmesinin yakınında) bir "Değişiklikleri İptal" butonuna tıklayın tıklayarak başka bir "Emin misiniz?" Tıklama yoluyla kullanıcı gerektirir mesaj kutusu ve sadece ağaçla tekrar gezin.