我使用ControlTemplate和GridViewRowPresenter的堆栈面板在WPF中实现了一个带有列的树视图.我按照这篇文章:http://blogs.msdn.com/b/atc_avalon_team/archive/2006/03/01/541206.aspx
它完美无缺!
但是,我希望在水平滚动时保持左列(带名称)可见.
这就像第一列上的microsoft excel上的'冻结窗格'.
一个想法,任何人?
谢谢弗雷德里克
该解决GridViewRowPresenter
方案的问题在于树与其他列不可分割.我认为你需要它是独立的,这样你就可以将水平仅ScrollViewer
放在列的周围,我怀疑这对你链接的文章中的项目很容易(如果可能的话).
这个项目,我一起打算弄清楚的东西是非常粗糙的边缘.您需要单独解决许多问题我没有进行微调:
GridView
标题和列的链接项目的各个方面.与文章项目一样,我使用了一个Type
对象树作为数据源.
让这个工作的关键是将数据对象包装在一个ExpandingContainer
对象中.这个INPC类的重要内容是IsExpanded
属性(用于绑定)和子集合:
public class ExpandingContainer : INotifyPropertyChanged {
public object Payload { get; private set; }
public ObservableCollection<ExpandingContainer> Children { get; private set; }
public ExpandingContainer( object payload ) { ... }
private bool _isexpanded;
public bool IsExpanded {
get { return _isexpanded; }
set {
if ( value == _isexpanded )
return;
_isexpanded = value;
PropertyChanged.Notify( () => IsExpanded );
}
}
public event PropertyChangedEventHandler PropertyChanged = (o,e) => {};
}
Run Code Online (Sandbox Code Playgroud)
至于XAML,首先让我们获取一些资源:
<!-- bind ExpandingContainer.IsExpanded to TreeViewItem.IsExpanded -->
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded"
Value="{Binding IsExpanded, Mode=TwoWay}" />
</Style>
<!-- for binding ExpandingContainer.IsExpanded to visibility later -->
<BooleanToVisibilityConverter x:Key="boolvis" />
<!-- the TreeViewItems should display the Type's name -->
<HierarchicalDataTemplate DataType="{x:Type loc:ExpandingContainer}"
x:Key="treeViewSide"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Payload.Name}" />
</HierarchicalDataTemplate>
<!-- the column side are naively simple, the ItemsControl of children has its
visibility bound to ExpandingContainer, but the "columns" are just
StackPanels of TextBlocks -->
<HierarchicalDataTemplate DataType="{x:Type loc:ExpandingContainer}"
x:Key="columnSide">
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10,0" />
</Style>
</StackPanel.Resources>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Payload.IsAbstract}" />
<TextBlock Text="{Binding Payload.Namespace}" />
<TextBlock Text="{Binding Payload.GUID}" />
</StackPanel>
<ItemsControl ItemsSource="{Binding Children}"
Visibility="{Binding IsExpanded, Converter={StaticResource boolvis}}" />
</StackPanel>
</HierarchicalDataTemplate>
<!-- a style can't refer to itself, so this was just to apply it to all ItemsControls -->
<Style TargetType="ItemsControl">
<Setter Property="ItemTemplate"
Value="{StaticResource columnSide}" />
</Style>
Run Code Online (Sandbox Code Playgroud)
我本来试图嵌套水平仅ScrollViewer
垂直仅含有内正确的列ScrollViewer
,这是负责的TreeView
,但产生的,你必须滚动至底部水平滚动奇怪的规定.所以我将它们进一步分开,并排放在一起ScrollViewer
.
为了使垂直滚动条保持在最右边,我将两个滚动条隐藏在周围,TreeView
并仅使用列周围的滚动条.同步垂直滚动是在代码隐藏中完成的,但是对于更多的MVVM方法,您可以创建一个附加行为以便于将它们相互绑定.
<DockPanel>
<ScrollViewer VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Hidden"
DockPanel.Dock="Left"
Name="treescroller">
<TreeView ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource treeViewSide}"
Padding="0,0,0,20">
</TreeView>
</ScrollViewer>
<ScrollViewer Name="columnscroller"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
ScrollChanged="columnscroller_ScrollChanged">
<ItemsControl ItemsSource="{Binding Items}" />
</ScrollViewer>
</DockPanel>
Run Code Online (Sandbox Code Playgroud)
最后,代码隐藏的重要部分(减去数据对象和设置DataContext
属性):
private void columnscroller_ScrollChanged( object sender, ScrollChangedEventArgs e ) {
treescroller.ScrollToVerticalOffset( columnscroller.VerticalOffset );
}
Run Code Online (Sandbox Code Playgroud)
希望它有所帮助,或者至少提供不同的视角.
如果我真的需要一个满足我对混合动力TreeView
+的所有需求的好的ListView
,我可能会先花一些时间来研究专业控制,然后花费必要的时间来完善自己的解决方案.当这种显示的要求很简单时,这种情况会更好.
归档时间: |
|
查看次数: |
1980 次 |
最近记录: |