2015-10-20 49 views
1

无论何时在我的树形视图中选择一个节点,它都会自动进行横向滚动。 I've found the way to disable this。如果我在后面的代码使用此代码,它完美的作品:防止TreeView中的自动水平滚动不起作用。 MVVM,XAML方法

<TreeView> 
    <TreeView.ItemContainerStyle> 
     <Style TargetType="TreeViewItem"> 
     <EventSetter Event="RequestBringIntoView" Handler="TreeViewItem_RequestBringIntoView"/> 
     </Style> 
    </TreeView.ItemContainerStyle> 
</TreeView> 

private void TreeViewItem_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e) 
{ 
    e.Handled = true; 
} 

不过,如果我使用MVVM,我不能禁用水平滚动的项目:

我的窗口:

<Window x:Class="TreeViewWpfApplication.MainWindow" 
    . . . . . 
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    xmlns:ei=http://schemas.microsoft.com/expression/2010/interactions> 
    <TreeView Grid.Column="1" Margin="5" Background="Green"> 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="RequestBringIntoView"> 
       <ei:CallMethodAction MethodName="RequestBringIntoView_Handler" TargetObject="{Binding}"/> 
      </i:EventTrigger> 
     </i:Interaction.Triggers> 

<TreeView> 
    <TreeViewItem Header="---Level 1" > 
     <TreeViewItem Header="--- Level 2.1" > 
      <TreeViewItem Header="--- Level 3.1" > 
      </TreeViewItem> 
     </TreeViewItem> 
    </TreeViewItem> 
    <TreeViewItem Header="Level 2.3" />   
    </TreeView> 
</Window> 

ViewModel:

public void RequestBringIntoView_Handler(object sender, RequestBringIntoViewEventArgs e) 
{ 
    e.Handled = true;   
} 

为什么我不能停止自动水平滚动到通过MVVM的方法?

+0

XAML *方法。 MVVM是一种分离问题的模式,XAML是您用来制作UI的工具。 –

+1

你有没有试过设置一些断点来检查处理程序是否被解雇? –

+0

@KingKing,是的,我有。处理程序被解雇。但是,处理程序不会阻止水平滚动到该项目。但是,它在代码背后完美运行。我无法弄清楚我做错了什么。 – StepUp

回答

1

我相信每一个连接一个克隆每个TreeViewItemInteraction.Triggers之前,你总是可以遍历TreeView的所有TreeViewItem和克隆从附着在TreeViewInteraction.Triggers每个TriggerBase

我对微软很失望,自从我开始学习如何编程以来,这个名字让我感到自豪,并且一直是我无尽的灵感。但坦率地说,微软让我们很失望。你的代码实际上应该可以正常工作。为什么?我试过了,事件RequestBringIntoView实际上从TreeViewItemTreeView。事实上,当你直接在TreeView上添加事件处理程序时,你会看到事件处理程序被触发OK。但使用Interaction的设置处理程序的非常同等形式不适用于此方式。这太可怕了。很明显,它旨在以MVVM方式设置事件处理程序,但它非常有限。

我不得不做一个解决方法,我们使用自定义附加属性来允许在样式中设置Interaction.Triggers。不过,我不得不说,它不是很漂亮。你需要明确声明一个ArrayTriggerBase(我以前做过这样的事情,但从来没有找到更好的解决方案)。接下来,您需要使用代理绑定TargetObject,EventTrigger(因为我们将触发器放在数组中,并且它与可视化树分离)。

下面是自定义附加属性的代码:

//add some using alias like this first 
//using i = System.Windows.Interactivity; 
public static class InteractionX 
{ 
    public static readonly DependencyProperty TriggersProperty 
     = DependencyProperty.RegisterAttached("Triggers", typeof(i.TriggerBase[]), 
      typeof(InteractionX), new PropertyMetadata(triggersChanged)); 
    public static i.TriggerBase[] GetTriggers(DependencyObject o){ 
     return o.GetValue(TriggersProperty) as i.TriggerBase[]; 
    } 
    public static void SetTriggers(DependencyObject o, i.TriggerBase[] value) 
    { 
     o.SetValue(TriggersProperty, value); 
    } 
    static void triggersChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) 
    { 
     var triggers = e.NewValue as i.TriggerBase[]; 
     var currentTriggers = i.Interaction.GetTriggers(o); 
     currentTriggers.Clear(); 
     foreach (var t in triggers) 
     { 
      t.Detach(); 
      currentTriggers.Add(t); 
     } 
    } 
} 

这里是XAML:

<TreeView> 
    <TreeView.Resources> 
    <DiscreteObjectKeyFrame x:Key="proxy" Value="{Binding}"/> 
    </TreeView.Resources> 
    <TreeView.ItemContainerStyle> 
     <Style TargetType="TreeViewItem"> 
     <Setter Property="local:InteractionX.Triggers"> 
       <Setter.Value>    
        <x:Array Type="{x:Type i:TriggerBase}"> 
         <i:EventTrigger EventName="RequestBringIntoView"> 
          <ei:CallMethodAction MethodName="bringIntoViewHandler" 
          TargetObject="{Binding Value, Source={StaticResource proxy}}"/> 
         </i:EventTrigger> 
        </x:Array> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </TreeView.ItemContainerStyle> 
</TreeView> 

看来,Interaction.Triggers集上TreeViewItem可以处理来自后代冒泡式RequestBringIntoView TreeViewItems,但正如我所说的,很可惜在TreeView上设置不起作用。

+1

非常感谢!你是编程的高手!你是英雄!:) – StepUp