如何取消用户的WPF TreeView点击?

Zac*_*son 12 wpf treeview savechanges

我有一个带有Treeview控件的WPF应用程序.

当用户单击树上的节点时,页面上的其他TextBox,ComboBox等控件将填充适当的值.

然后,用户可以更改这些值,并通过单击"保存"按钮保存其更改.

但是,如果用户选择不同的Treeview节点而不保存其更改,我想显示警告并取消该选择的机会.

MessageBox:继续并放弃未保存的更改?确定/取消http://img522.imageshack.us/img522/2897/discardsj3.gif

XAML ...

<TreeView Name="TreeViewThings"
    ...
    TreeViewItem.Unselected="TreeViewThings_Unselected"
    TreeViewItem.Selected="TreeViewThings_Selected" >
Run Code Online (Sandbox Code Playgroud)

Visual Basic ......

Sub TreeViewThings_Unselected(ByVal sender As System.Object, _
                              ByVal e As System.Windows.RoutedEventArgs)
    Dim OldThing As Thing = DirectCast(e.OriginalSource.DataContext, Thing)
    If CancelDueToUnsavedChanges(OldThing) Then
        'put canceling code here
    End If
End Sub

Sub TreeViewThings_Selected(ByVal sender As System.Object, _
                            ByVal e As System.Windows.RoutedEventArgs)
    Dim NewThing As Thing = DirectCast(e.OriginalSource.DataContext, Thing)
    PopulateControlsFromThing(NewThing)
End Sub

如何取消这些取消选择/选择事件?


更新:我问过一个后续问题......
如何使用MessageBox确认正确处理PreviewMouseDown事件?

Fre*_*lad 11

UPDATE

意识到我可以将逻辑放在SelectedItemChanged中.一个小清洁解决方案.

XAML

<TreeView Name="c_treeView"
          SelectedItemChanged="c_treeView_SelectedItemChanged">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>
Run Code Online (Sandbox Code Playgroud)

代码背后.我有一些类是TreeView的ItemsSource,所以我创建了一个接口(MyInterface),为所有这些类公开了IsSelected属性.

private MyInterface m_selectedTreeViewItem = null;
private void c_treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    if (m_selectedTreeViewItem != null)
    {
        if (e.NewValue == m_selectedTreeViewItem)
        {
            // Will only end up here when reversing item
            // Without this line childs can't be selected
            // twice if "No" was pressed in the question..   
            c_treeView.Focus();   
        }
        else
        {
            if (MessageBox.Show("Change TreeViewItem?",
                                "Really change",
                                MessageBoxButton.YesNo,
                                MessageBoxImage.Question) != MessageBoxResult.Yes)
            {
                EventHandler eventHandler = null;
                eventHandler = new EventHandler(delegate
                {
                    c_treeView.LayoutUpdated -= eventHandler;
                    m_selectedTreeViewItem.IsSelected = true;
                });
                // Will be fired after SelectedItemChanged, to early to change back here
                c_treeView.LayoutUpdated += eventHandler;
            }   
            else
            {
                m_selectedTreeViewItem = e.NewValue as MyInterface;
            }        
        }
    }
    else
    {
        m_selectedTreeViewItem = e.NewValue as MyInterface;
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有发现在按"否"时它没有恢复到上一个​​项目的任何情况.


Ecl*_*pse 1

由于该SelectedItemChanged事件是在SelectedItem已经更改后触发的,因此此时您无法真正取消该事件。

您可以做的是监听鼠标点击并在SelectedItem更改之前取消它们。