繁体   English   中英

防止TreeView中的自动水平滚动不起作用。 MVVM,XAML方法

[英]Prevent Automatic Horizontal Scroll in TreeView is not working. MVVM, XAML approach

每当在我的树视图中选择一个节点时,它都会自动水平滚动到该项目。 我找到了禁用此功能的方法 如果我在后面的代码中使用此代码,则效果很好:

<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>

视图模型:

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

为什么不能通过MVVM方法停止自动水平滚动到该项目?

我相信,你总是可以遍历所有TreeViewItem中的TreeView和克隆每个TriggerBaseInteraction.Triggers附着在TreeView连接每个克隆一到之前Interaction.Triggers每一个TreeViewItem

我对Microsoft感到非常失望,自从我开始学习如何编程以来,这个名字让我感到骄傲并成为我多年的无穷灵感。 但坦率地说,微软让我们失望的很多事情。 您的代码实际上应该可以正常工作。 为什么? 我已经尝试过了,事件RequestBringIntoView实际上从TreeViewItem冒泡到TreeView 实际上,当您直接在TreeView上添加事件处理程序时,您会看到事件处理程序被触发了。 但是使用Interaction的设置处理程序的等效形式无法正常工作。 太可怕了 显然,它是按MVVM方式设置事件处理程序的,但它是如此有限。

我必须进行变通,其中使用自定义附加属性来设置Style中的Interaction.Triggers 但是我不得不说这不是很漂亮。 您需要显式声明一个TriggerBase Array (我之前做过类似的事情,但是从未找到更好的解决方案)。 接下来,您需要使用代理为EventTrigger绑定TargetObject (因为我们将触发器放置在Array中,并将其与可视树分离)。

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

//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>

看来,在TreeViewItem设置的Interaction.Triggers可以处理从后代TreeViewItems起泡的RequestBringIntoView ,但正如我所说的,很遗憾在TreeView上设置该功能不起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM