我试图在WPF TreeView
中的顶级层次结构项之间提供分隔(边距)。问题是,我无法弄清楚如何编写Style
,只能应用于顶级项目而不是每个项目。
我TreeView
的代码如下所示:
<TreeView ItemContainerStyle="{StaticResource treeViewItemStyle}"
ItemsSource="{Binding Container.RootRules}"
KeyUp="treeView_KeyUp"
SelectedItemChanged="TreeView_SelectedItemChanged">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type me:HybridForecastRulesViewModel}"
ItemsSource="{Binding Children}">
<Border Name="bd"
...
</Border>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type me:RootRulesViewModel}"
ItemsSource="{Binding Rules}">
<Grid>
...
</Grid>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
我有一个像这样的treeViewItems样式:
<Style x:Key="treeViewItemStyle"
BasedOn="{StaticResource {x:Type TreeViewItem}}"
TargetType="{x:Type TreeViewItem}">
<Setter Property="Margin" Value="0,10,0,0" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
但是,当我希望它仅适用于RootRulesViewModel
类型的项目时,此样式适用于这两种类型的项目(HybridForecastRulesViewModel
和RootRulesViewModel
)。如何才能做到这一点?
除了第一个RootRulesViewModel
之外,所有Margin
个项目的最高[Exception:Cant get object from dataabase for blabla.... at NHibernate.Proxy.CastleProxyFactory.GetProxy(Object id, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.CreateProxy(Object id, ISessionImplementor session)
at NHibernate.Impl.SessionImpl.DoLoadByClass(Type clazz, Object id, Boolean checkDeleted, Boolean allowProxyCreation)
at NHibernate.Impl.SessionImpl.InternalLoad(Type clazz, Object id)
at NHibernate.Type.ManyToOneType.ResolveIdentifier(Object id, ISessionImplementor session)
at NHibernate.Type.EntityType.ResolveIdentifier(Object id, ISessionImplementor session, Object owner)
at NHibernate.Impl.SessionImpl.InitializeEntity(Object obj)
at NHibernate.Loader.Loader.InitializeEntitiesAndCollections(IList hydratedObjects, Object resultSetId, ISessionImplementor session)
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
at NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters)
at NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet querySpaces, IType[] resultTypes)
at NHibernate.Loader.Criteria.CriteriaLoader.List(ISessionImplementor session)
at NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria, IList results)
at NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria)
at NHibernate.Impl.CriteriaImpl.List()
at Main.GetUser() in c:\inetpub\app\WebSites\app\App_Code\Main.cs:line 40]
Main.GetUser() in c:\inetpub\app\WebSites\app\App_Code\Main.cs:53
GetData..ctor() in c:\inetpub\app\WebSites\app\App_Code\GetsData.cs:20
Start..ctor() in c:\inetpub\app\WebSites\app\Start.aspx.cs:28
ASP.begin_aspx..ctor() in c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\root\940436d6\b67d273a\App_Web_zf-pdvkp.10.cs:0
__ASP.FastObjectFactory_app_web_zf_pdvkp.Create_ASP_begin_aspx() in c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\root\940436d6\b67d273a\App_Web_zf-pdvkp.18.cs:0
System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp, Boolean noAssert) +138
System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath) +50
System.Web.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +425
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +263
都是锦上添花。
答案 0 :(得分:1)
TreeViewItem
没有Level
属性可供使用。
所以你有两个选择:
1)this。看看TreeLevelConverter
,这很有趣。它们绑定控件本身并使用转换器来检索Level
。在您的情况下,您可以在检索Level
后扩展转换器,将其转换为Thickness
实例以用作Margin
。
2)您可以在Level
上创建ViewModels
属性(可能在其基类中,以避免代码重复)。然后,每次将子项添加到ViewModel
节点时,都会在该子项上设置Level
。在xaml中,您将Margin
属性绑定到Level
上的ViewModel
,使用转换器返回不同的Thickness
,具体取决于Level
是否为1或不
修改强>
这是您为所有Style
:
TreeViewItem
的方法
<TreeView>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter 1 .../>
<Setter 2 .../>
<Setter Property="Margin"
Value="{Binding Level, Converter={StaticResource LevelToMarginConverter}}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<!-- here your hierarchical DataTemplate... -->
<HierarchicalDataTemplate ... />
</TreeView.Resources>
</TreeView>
答案 1 :(得分:0)
我实际上最终得到了一个解决方案。我不确定它有多好,所以可以提出改进建议。
我已经从this answer编写了一个对象转换器,以获取Header
的{{1}}中的对象类型。
代码如下所示:
TreeViewItem
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Header, Converter={StaticResource ObjectTypeConverter}}"
Value="RootRulesViewModel">
<Setter Property="Margin"
Value="0,0,0,10" />
</DataTrigger>
<DataTrigger Binding="{Binding IsVisible}"
Value="False">
<Setter Property="Visibility"
Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
是我的自定义转换器,它将对象类型转换为字符串值。