2013-11-27 3 views
4

Есть ли способ захватить попытку изменить выбранный вами элемент в TreeView WPF и, возможно, отменить его?WPF, изменение выбора Treeview

Элементы в древовидной структуре представляют собой страницы с некоторыми свойствами. Я хотел бы спросить пользователя, хочет ли он отказаться от изменений, внесенных на страницу, сохранить их или остаться на текущей странице.

+0

Есть ли возможность достичь этого, обратившись к PreviewMouseDown (e.Handled = true). – Ravuthasamy

ответ

2

Ну, вам, вероятно, не понравится ответ ... WPF TreeView - недружелюбный парень. Хорошо, первые вещи первые ...

захватывая попытку изменить выбранный элемент:

Самый простой способ сделать это, чтобы справиться с SelectedItemChanged событие:

private void TreeView_SelectedItemChanged(object sender, 
RoutedPropertyChangedEventArgs<object> e) 
{ 
    e.Handled = true; 
} 

К сожалению, если вы используете MVVM, вам необходимо обработать его внутри Attached Property. Теперь немного усложнись, если вы собираетесь создать Attached Property для обработки события SelectedItemChanged, тогда вы можете также реализовать SelectedItemAttached Property, с которым вы могли бы связываться в Two-Way Mode. Я не буду документировать, как это сделать, потому что для этого есть много онлайн-руководств.

... и, возможно, отменить его:

Если у вас есть SelectedItemAttached Property, то вы можете контролировать, когда, что изменения свойств. Конечно, есть уловка ... к моменту внесения изменений в вашу модель представления пользовательский интерфейс уже изменился. Таким образом, хотя вы можете остановить изменение, происходящее с данными в модели представления, вы не можете остановить выбор, сделанный в пользовательском интерфейсе.

Это не страшная проблема, хотя, потому что с Two-Way Binding, вы сможете установить выбор интерфейса вернуться к предыдущему пункту, если это необходимо ... посмотрите на этот псевдо-код:

public YourDataType SelectedItem 
{ 
    get { return selectedItem; } 
    set 
    { 
     if (selectedItem != value) 
     { 
      if (selectedItem.HasChanges) 
      { 
       if (WindowManager.UserAcceptsLoss()) 
       { 
        selectedItem = value; 
        NotifyPropertyChanged("SelectedItem"); 
       } 
       else ResetSelectedItem(selectedItem); 
      } 
      else 
      { 
       selectedItem = value; 
       NotifyPropertyChanged("SelectedItem"); 
      } 
     } 
    } 
} 

Для выполнения ваших требований у вас впереди много работы ... удачи в этом.

+0

Вы правы, мне не нравится этот ответ :( – Spook

7

Для гораздо более простого решения. Переопределите PreviewMouseDown и получите желаемый результат.

private void Tree_OnPreviewMouseDown(object sender, MouseButtonEventArgs e) 
    { 
     // first did the user click on a tree node? 
     var source = e.OriginalSource as DependencyObject; 
     while (source != null && !(source is TreeViewItem)) 
      source = VisualTreeHelper.GetParent(source); 
     source = source as TreeViewItem; 
     if (source == null) return; 

     var treeView = sender as TreeView; 
     if (treeView == null) return; 

     // validate our current item to decide if we allow the change 
     // or do whatever checks you wish 
     if (!ItemIsValid(treeView.SelectedItem)) 
     { 
      // it's not valid, so cancel the attempt to select an item. 
      e.Handled = true; 
     } 

     // Maybe you want to check the about to be selected value? 
     MyClass data = source.DataContext; 
     if (!CanSelect(data)) 
     { 
      // we can't select this, so cancel the attempt to select. 
      e.Handled = true; 
     } 
    } 
+0

Это должен быть принятый ответ. Простой и точно решает проблему. –

Смежные вопросы