2015-10-20 27 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