自适应触发器和数据模板
Posted
技术标签:
【中文标题】自适应触发器和数据模板【英文标题】:AdaptiveTrigger and DataTemplate 【发布时间】:2015-11-12 08:09:18 【问题描述】:AdaptiveTrigger 可以在 DataTemplate 中工作吗?
这是我用来自定义 ShellNavigation 的代码,除了视觉状态外,它工作正常。他们不会触发任何事情。
<shell:ShellHeadView x:Key="ShellHeadView_01">
<shell:ShellHeadView.ContentTemplate>
<DataTemplate>
<Grid Margin="20,0">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="GreenBackgroundVisualState">
<VisualState.Setters>
<Setter Target="headViewLeft.Background" Value="Green" />
</VisualState.Setters>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1000"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="OrangeBackgroundVisualState">
<VisualState.Setters>
<Setter Target="headViewLeft.Background" Value="Orange" />
</VisualState.Setters>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="2000"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="RedBackgroundVisualState">
<VisualState.Setters>
<Setter Target="headViewLeft.Background" Value="Red" />
</VisualState.Setters>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="3000"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" x:Name="headViewLeft" Width="100" Height="90">
</Grid>
【问题讨论】:
【参考方案1】:尝试像这样将您的 DataTemplate
包裹在 UserControl
中 -
<DataTemplate>
<UserControl>
<Grid>
<VisualStateManager.VisualStateGroups>
...
</Grid>
</UserControl>
</DataTemplate>
看起来任何具有Content
属性的Control
都可以工作。这就是 UserControl
有效的原因,ContentControl
也是如此。
因此,如果您将 UserControl
替换为 ContentControl
并给它一个空的 Style
。它也应该可以工作。
<Style x:Key="EmptyContentControlStyle" TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl" />
</Setter.Value>
</Setter>
</Style>
<DataTemplate>
<ContentControl Style="StaticResource EmptyContentControlStyle">
<Grid>
<VisualStateManager.VisualStateGroups>
...
</Grid>
</ContentControl>
</DataTemplate>
【讨论】:
如何使用它来使动态创建的列表项工作?ListView listView = new ListView(); listView.ItemsSource = source.Articles; listView.Template = ???; listView.IsItemClickEnabled = true; listView.ItemClick += OpenArticle_ItemClick; listView.SelectionMode = ListViewSelectionMode.None;
FWIW,UserControl
效果很好,但ContentControl
不行。仍然是一个很好的答案!
@EricLiprandi 嗯,你给你的 ContentControl 一个空样式了吗?
我错过了那部分:) - 我想UserControl
对我来说更干净......我想不出在这种情况下UserControl
和ContentControl
之间的功能差异。
这里是另一个answer,用于处理ListView
的DataTemplate
中的状态。【参考方案2】:
创建两个数据模板。使用自适应触发器更改您的ItemsControl
上的ItemTemplate
TBH 将自适应触发器放在通用模板中而不是页面视图中对我来说有点奇怪。
一般来说,我强烈建议不要将用户控件放在数据模板中,如另一个答案中所建议的那样。用户控件很慢,因此将它们放在模板中反复使用可能会降低性能(带有控件模板的自定义控件是更好的选择)。
您还可以创建一个在模板之间切换的自定义控件。示例:
public class AdaptiveControl : ContentControl
public AdaptiveControl()
SizeChanged += AdaptiveControl_SizeChanged;
private void AdaptiveControl_SizeChanged(object sender, SizeChangedEventArgs e)
Update();
private void Update()
if (ActualWidth < Size)
ContentTemplate = SmallTemplate;
else
ContentTemplate = LargeTemplate;
public double Size
get return (double)GetValue(SizeProperty);
set SetValue(SizeProperty, value);
public static readonly DependencyProperty SizeProperty =
DependencyProperty.Register(nameof(Size), typeof(double), typeof(AdaptiveControl), new PropertyMetadata(200d, (s, e) => ((AdaptiveControl)s).Update()));
public DataTemplate SmallTemplate
get return (DataTemplate)GetValue(SmallTemplateProperty);
set SetValue(SmallTemplateProperty, value);
public static readonly DependencyProperty SmallTemplateProperty =
DependencyProperty.Register(nameof(SmallTemplate), typeof(DataTemplate), typeof(AdaptiveControl), new PropertyMetadata(null, (s, e) => ((AdaptiveControl)s).Update()));
public DataTemplate LargeTemplate
get return (DataTemplate)GetValue(LargeTemplateProperty);
set SetValue(LargeTemplateProperty, value);
public static readonly DependencyProperty LargeTemplateProperty =
DependencyProperty.Register(nameof(LargeTemplate), typeof(DataTemplate), typeof(AdaptiveControl), new PropertyMetadata(null, (s, e) => ((AdaptiveControl)s).Update()));
【讨论】:
以上是关于自适应触发器和数据模板的主要内容,如果未能解决你的问题,请参考以下文章