2010-08-03 4 views
2

안녕하세요, Silverlight의 TreeView 컨트롤에 대한 질문이 있습니다.Silverlight TreeView ScrollViewer 문제

동적으로 요소를 트리 뷰에 추가하는 응용 프로그램이 있습니다. 요소 중 일부는 가로 스크롤이 필요할만큼 길다. 트리 뷰에 트리 뷰가 추가되면 트리 뷰는 왼쪽으로 스크롤 된 상태를 유지하기 때문에 스크롤하여 항목의 끝을 확인해야합니다. 그러나 내가 트리 뷰를 숨기는 항목을 클릭 한 다음 '결과로 돌아 가기'버튼을 사용하면 트리 뷰가 표시되고 자동으로 해당 항목으로 스크롤됩니다. 센터.

아무도 결과로 돌아 왔을 때 왼쪽으로 모든 방법을 스크롤하려면 treeview 얻을 수있는 방법을 알고 있습니까? 내가 트 리뷰 템플릿을 장난 해봤

: 내가 뒤에있는 코드에서 ScrollViewer에 액세스하는 방법을 모르고있다

<Style TargetType="controls:TreeView" x:Name="SCREW"> 
      <Setter Property="Background" Value="#FFFFFFFF" /> 
      <Setter Property="Foreground" Value="#FF000000" /> 
      <Setter Property="HorizontalContentAlignment" Value="Left" /> 
      <Setter Property="VerticalContentAlignment" Value="Top" /> 
      <Setter Property="Cursor" Value="Arrow" /> 
      <Setter Property="BorderThickness" Value="1" /> 
      <Setter Property="Padding" Value="1" /> 
      <Setter Property="BorderBrush" Value="#FF000000" /> 
      <Setter Property="IsTabStop" Value="True" /> 
      <Setter Property="TabNavigation" Value="Once" /> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="controls:TreeView" x:Name="SCREWTEMPLATE"> 
         <Grid> 
          <VisualStateManager.VisualStateGroups> 
           <VisualStateGroup x:Name="CommonStates"> 
            <VisualState x:Name="Normal" /> 
            <VisualState x:Name="MouseOver" /> 
            <VisualState x:Name="Pressed" /> 
            <VisualState x:Name="Disabled" /> 
           </VisualStateGroup> 
           <VisualStateGroup x:Name="FocusStates"> 
            <VisualState x:Name="Unfocused" /> 
            <VisualState x:Name="Focused" /> 
           </VisualStateGroup> 
           <VisualStateGroup x:Name="ValidationStates"> 
            <VisualState x:Name="Valid" /> 
            <VisualState x:Name="InvalidUnfocused"> 
             <Storyboard> 
              <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Validation" Storyboard.TargetProperty="Visibility"> 
               <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> 
              </ObjectAnimationUsingKeyFrames> 
             </Storyboard> 
            </VisualState> 
            <VisualState x:Name="InvalidFocused"> 
             <Storyboard> 
              <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Validation" Storyboard.TargetProperty="Visibility"> 
               <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> 
              </ObjectAnimationUsingKeyFrames> 
              <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationToolTip" Storyboard.TargetProperty="IsOpen"> 
               <DiscreteObjectKeyFrame KeyTime="0"> 
                <DiscreteObjectKeyFrame.Value> 
                 <System:Boolean>True</System:Boolean> 
                </DiscreteObjectKeyFrame.Value> 
               </DiscreteObjectKeyFrame> 
              </ObjectAnimationUsingKeyFrames> 
             </Storyboard> 
            </VisualState> 
           </VisualStateGroup> 
          </VisualStateManager.VisualStateGroups> 

          <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"> 
           <Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" Margin="1"> 
            <ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Background="{x:Null}" BorderBrush="Transparent" BorderThickness="0" IsTabStop="False" TabNavigation="Once" Loaded="ScrollViewer_Loaded"> 
             <ItemsPresenter Margin="5" /> 
            </ScrollViewer> 
           </Border> 
          </Border> 

          <Border x:Name="Validation" Grid.Column="1" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="#FFDB000C" CornerRadius="2" Visibility="Collapsed"> 
           <ToolTipService.ToolTip> 
            <ToolTip x:Name="ValidationToolTip" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" IsHitTestVisible="True" /> 
           </ToolTipService.ToolTip> 
           <Grid Width="10" Height="10" HorizontalAlignment="Right" Margin="0,-4,-4,0" VerticalAlignment="Top" Background="Transparent"> 
            <Path Margin="-1,3,0,0" Fill="#FFDC000C" Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 Z" /> 
            <Path Margin="-1,3,0,0" Fill="#FFFFFFFF" Data="M 0,0 L2,0 L 8,6 L8,8" /> 
           </Grid> 
          </Border> 
         </Grid> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

그러나의 문제 ... 그래서 호출 할 수 없습니다 ScrollView.setScrollOffset (0d, 0d) 또는 그런 것.

아이디어가 있으십니까? 대단히 감사합니다.

마지막으로 한 가지는 treeview를 확장하는 새로운 컨트롤을 구현하지 않는 것이 좋습니다. C# 코드 숨김에서 제어 템플릿과 관련된 함수를 액세스/수정하고 사용하는 방법이 있기를 정말로 바라고 있습니다.

답변

0

나는 이것을 위해 연결된 속성을 설정하고 거기에 원하는 논리를 만들었습니다. 그런 다음 첨부 된 속성으로 트리보기를 꾸미십시오.

var offset = this.HorizontalScrollOffsetAfterSelect; // would be 0 if you don't want to make that adjustable 
if (!Double.IsNaN(offset)) 
{ 
    var scrollViewer = trv.GetVisualDescendants().OfType<ScrollViewer>().FirstOrDefault(); 
    if (scrollViewer != null) 
    { 
     scrollViewer.ScrollToHorizontalOffset(offset); 
     // and because that wasn't enough because of timing issues: 
     var scrollBar = scrollViewer.GetVisualDescendants().OfType<ScrollBar>().Where(cur => cur.Orientation == Orientation.Horizontal).FirstOrDefault(); 
     if (scrollBar != null) 
     { 
      RoutedPropertyChangedEventHandler<double> handler = null; 
      handler = (sender, e) => 
       { 
        scrollBar.ValueChanged -= handler; 

        scrollViewer.ScrollToHorizontalOffset(offset); 
       }; 
      scrollBar.ValueChanged += handler; 
     } 
    } 
} 

가 요구합니다 TreeViewSelectedItemChanged 이벤트를 처리 한 후

나는 행동으로이 코드를 넣어
public class ScrollResetService 
{ 
    public static DependencyProperty IsScrollResetProperty = DependencyProperty.RegisterAttached("IsScrollReset", 
                           typeof(bool), 
                           typeof(ScrollResetService), 
                           new PropertyMetadata(false, 
                             OnIsScrollResetChanged)); 
    public static void SetIsScrollReset(DependencyObject d, bool value) 
    { 
     d.SetValue(IsScrollResetProperty, value); 
    } 

    public static bool GetIsScrollReset(DependencyObject d) 
    { 
     return d.GetValue(IsScrollResetProperty) == null ? false : (bool)d.GetValue(IsScrollResetProperty); 
    } 

    private static void OnIsScrollResetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var treeView = d as TreeView; 
     bool isScrollReset; 
     if (e.NewValue!= null && bool.TryParse(e.NewValue.ToString(), out isScrollReset) && treeView != null) 
     { 

      treeView.SelectedItemChanged += (sender, args) => 
               { 
                var scrolls = 
                 treeView.GetAllLogicalChildrenOfType<IScrollInfo>(); 
                scrolls.ForEach(i => i.SetVerticalOffset(0)); 
               }; 

     } 
    } 

} 

public static class Extensions 
    { 

public static IEnumerable<T> GetAllLogicalChildrenOfType<T>(this FrameworkElement parent) 
     { 
      Debug.Assert(parent != null, "The parent cannot be null."); 
      return parent.GetVisualChildren().Flatten(item => item.GetVisualChildren()).OfType<T>(); 
     } 

public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items, Func<T, IEnumerable<T>> childSelector) 
     { 
      if (items == null) return Enumerable.Empty<T>(); 
      return items.Concat(items.SelectMany(i => childSelector(i).Flatten(childSelector))); 
     } 

internal static IEnumerable<DependencyObject> GetVisualChildren(this DependencyObject parent) 
     { 
      int childCount = VisualTreeHelper.GetChildrenCount(parent); 
      for (int counter = 0; counter < childCount; counter++) 
      { 
       yield return VisualTreeHelper.GetChild(parent, counter); 
      } 
     } 
} 
+0

죄송합니다. 작동하는 것처럼 들리지만 조금만 더 도와 주셔야합니다. 어떻게 사용합니까? 고마워, 만약이 작품이 내 인생을 빚 졌어! – NickHalden

0

은 (또한 뒤에 코드에서 일 것이다) : 우리는 scrollviewers를 포함하는 다른 컨트롤과 비슷한 할 using System.Linq;using System.Windows.Controls.Primitives; 및 Toolkit ofc.

지금까지 충분히 잘 작동합니다.

관련 문제