2012-11-29 68 views
2

如果ListBox的垂直滾動條被摺疊,我想調整放置在獨立ListBox上的Border或Margin的寬度或可見性。如何將DataTrigger綁定到單獨的ListBox ScrollViewer的ComputedVerticalScrollBarVisibility屬性?

我想這樣的事情,但無法弄清楚如何到達ListBox ScrollViewer。顯然,DataTrigger中的路徑不正確。

<Border Width={Binding Source={x:Static SystemParameters.ScrollWidth}}"> 
    <Border.Style> 
     <Style> 
     <Setter Property="Border.Visibility" Value="Visible"/> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ElementName=listBox, 
         Path=***ScrollViewer.ComputedVerticalScrollBarVisibility***}" 
         Value="Collapsed"> 
       <Setter Property="Border.Visibility" Value="Collapsed"/> 
      </DataTrigger> 
     </Style.Triggers> 
     </Style> 
    </Border.Style> 
</Border> 

<ListBox Name="listBox" ItemsSource="{Binding MyItems}"/> 

有沒有辦法到達那個ListBox屬性?如果沒有,是否有更好的方法來解決這個問題?

非常感謝!

+0

從我所知道的情況來看,在ListBox的「部件」中往往會很困難。我現在最好的解決方法是禁用ListBox中的滾動條並將ListBox包裝在ScrollViewer中。然後DataTrigger可以工作,如果我綁定到包裝ScrollViewer元素名稱並將Path設置爲ComputedVerticalScrollBarVisibility。 –

回答

3

在另一個ScrollViewer中包裝列表框的解決方法允許以犧牲冗餘ScrollViewer控件爲代價的全部XAML解決方案(請參閱問題中的評論)。最後,我的隊友決定採用如下代碼隱藏解決方案。

下面是我們需要訪問ScrollViewer的ListBox的相關屬性。

<ListBox Name="_listBox" ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
     Loaded="InitializeListBoxScrollViewerProperty"/> 

這裏是隱藏滾動查看器以供外部控件使用的代碼隱藏。

private static readonly DependencyPropertyKey ListBoxScrollViewerPropertyKey = 
    DependencyProperty.RegisterReadOnly("ListBoxScrollViewer", typeof(ScrollViewer), 
    typeof(MyEditView), new PropertyMetadata()); 

protected static readonly DependencyProperty ListBoxScrollViewerProperty = 
    ListBoxScrollViewerPropertyKey.DependencyProperty; 

protected ScrollViewer ListBoxScrollViewer 
{ 
    get { return (ScrollViewer)GetValue(ListBoxScrollViewerProperty); } 
    private set { SetValue(ListBoxScrollViewerPropertyKey, value); } 
} 

private void InitializeListBoxScrollViewerProperty(object sender, RoutedEventArgs args) 
{ 
    if (ReferenceEquals(args.OriginalSource, _listBox)) 
    { 
     var scrollViewer = _listBox.GetFirstDescendantBreadthFirst<ScrollViewer>(); 
     if (scrollViewer != null) 
     { 
     ListBoxScrollViewer = scrollViewer; 
     } 
    } 
} 

下面是使用的擴展方法:

public static class DependencyObjectExtensions 
{ 
    public static TDescendant GetFirstDescendantBreadthFirst<TDescendant> 
     (this DependencyObject dependencyObject) where TDescendant : DependencyObject 
    { 
     if (dependencyObject == null) { throw new ArgumentNullException(); } 
     return GetFirstDescendantBreadthFirst<TDescendant>(GetAllChildren(dependencyObject)); 
    } 

    private static TDescendant GetFirstDescendantBreadthFirst<TDescendant> 
     (IEnumerable<DependencyObject> descendants) where TDescendant : DependencyObject 
    { 
     if (!descendants.Any()) return null; 
     var descendant = descendants.OfType<TDescendant>().FirstOrDefault(); 
     if (descendant != null) return descendant; 
     return GetFirstDescendantBreadthFirst<TDescendant>(descendants.SelectMany(GetAllChildren)); 
    } 

    private static IEnumerable<DependencyObject> GetAllChildren(DependencyObject dependencyObject) 
    { 
     return Enumerable 
     .Range(0, VisualTreeHelper.GetChildrenCount(dependencyObject)) 
     .Select(i => VisualTreeHelper.GetChild(dependencyObject, i)); 
    } 
} 

最後,滾動觀衆可以在XAML的另一部分進行訪問。

<Grid> 
    <Grid.Style> 
     <Style TargetType="Grid"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ListBoxScrollViewer.ComputedVerticalScrollBarVisibility, 
       RelativeSource={RelativeSource AncestorType=l:MyEditView}}" Value="Visible"> 
       <Setter Property="Margin" Value="{StaticResource myWidenedMargin}"/> 
      </DataTrigger> 
     </Style.Triggers> 
     </Style> 
    </Grid.Style> 
</Grid> 
+0

您可以隨時編輯列表框的模板並刪除多餘的ScrollViewer。 – VeV

相關問題