使用 Trigger 更改 DataTemplate 时随机选择的项目
Posted
技术标签:
【中文标题】使用 Trigger 更改 DataTemplate 时随机选择的项目【英文标题】:Random selected item when using Trigger to change DataTemplate 【发布时间】:2019-06-20 00:16:20 【问题描述】:我正在尝试使用此代码更改我的ContentTemplate
:
<DataTemplate x:Key="SidebarItemStyle" DataType="x:Type domain:SidebarDataTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Grid.RowSpan="2" Fill="StaticResource BluePrimaryBrush" />
<Image Grid.Row="0" Style="StaticResource SidebarMenuImageSyle" Source="Binding Image" />
<TextBlock Grid.Row="1" Style="StaticResource SidebarMenuTextStyle" Text="Binding Title" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="SidebarSelectedItemStyle" DataType="x:Type domain:SidebarDataTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Grid.RowSpan="2" Fill="StaticResource BluePrimaryBrush" />
<Rectangle Grid.Row="0" Grid.RowSpan="2" Fill="StaticResource TransparentOverlay1Brush" />
<Image Grid.Row="0" Style="StaticResource SidebarMenuImageSyle" Source="Binding SelectedImage" />
<TextBlock Grid.Row="1" Style="StaticResource SidebarMenuTextStyle" Text="Binding Title" />
</Grid>
</DataTemplate>
<Style TargetType="x:Type ListBoxItem" x:Key="SidebarContainerStyle">
<Setter Property="ContentTemplate" Value="StaticResource SidebarItemStyle" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="StaticResource SidebarSelectedItemStyle" />
</Trigger>
</Style.Triggers>
</Style>
但是,当我单击该项目时,它会一直选择随机项目或仅选择第一个项目。关键是我想使用不同的Image
并为所选项目添加叠加层。
【问题讨论】:
【参考方案1】:我不确定你的情况是怎么回事,但你的ContentTemplate
从未定义ContentPresenter
有点可疑。无论如何,我认为还有另一种方法可以实现您的目标。尝试以下 XAML:
<ListBox ItemsSource="Binding Items">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Grid.RowSpan="2" Fill="StaticResource BluePrimaryBrush" />
<Rectangle Grid.Row="0" Grid.RowSpan="2" Fill="StaticResource TransparentOverlay1Brush">
<Rectangle.Style>
<Style TargetType="Rectangle">
<!-- Don't show overlay when not selected -->
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="Binding IsSelected, RelativeSource=RelativeSource FindAncestor, AncestorType=ListBoxItem" Value="True">
<!-- Show overlay when selected -->
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<Image Grid.Row="0">
<Image.Style>
<Style TargetType="Image">
<!-- Use Image when not selected -->
<Setter Property="Source" Value="Binding Image" />
<Style.Triggers>
<DataTrigger Binding="Binding IsSelected, RelativeSource=RelativeSource FindAncestor, AncestorType=ListBoxItem" Value="True">
<!-- Use SelectedImage when selected -->
<Setter Property="Source" Value="Binding SelectedImage" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<TextBlock Grid.Row="1" Text="Binding Title" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<!-- Remove default selection highlighting -->
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
您定义了一个ItemTemplate
,根据是否选择了它所在的ListBoxItem
,您可以选择是否使用覆盖和SelectedImage
属性。 ListBoxItem.ControlTemplate
被替换为空的 ContentPresenter
以删除所有默认突出显示(因为您自己这样做)。
【讨论】:
感谢您的回复,我已经解决了这个问题,请查看我的更新答案。【参考方案2】:原来这种奇怪的行为是由来自this post的DragMoveBehavior
引起的。
public class DragMoveBehavior : Behavior<Window>
protected override void OnAttached()
AssociatedObject.MouseMove += AssociatedObject_MouseMove;
protected override void OnDetaching()
AssociatedObject.MouseMove -= AssociatedObject_MouseMove;
private void AssociatedObject_MouseMove(object sender, MouseEventArgs e)
if (e.LeftButton == MouseButtonState.Pressed && sender is Window window)
// In maximum window state case, window will return normal state and
// continue moving follow cursor
if (window.WindowState == WindowState.Maximized)
window.WindowState = WindowState.Normal;
// 3 or any where you want to set window location after
// return from maximum state
Application.Current.MainWindow.Top = 3;
window.DragMove();
窗口 XAML:
<Window ...
xmlns:h="clr-namespace:A.Namespace.Of.DragMoveBehavior"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">
<i:Interaction.Behaviors>
<h:DragMoveBehavior />
</i:Interaction.Behaviors>
...
</Window>
通过从 Window 中删除该行为,这个奇怪的随机点击问题消失了。感谢redcurry 的回答,我也在我的应用中使用了你的代码。
更新
我将redcurry 标记为代码的可接受答案,但如果您遇到此问题,您可能需要先尝试他的解决方案,然后再尝试我的解决方案。
【讨论】:
以上是关于使用 Trigger 更改 DataTemplate 时随机选择的项目的主要内容,如果未能解决你的问题,请参考以下文章
使用 Trigger 更改 DataTemplate 时随机选择的项目
RefluxJS 商店可以在调用 trigger() 时指示哪些属性已更改?
在 MySQL 的 TRIGGER 中更改 LAST_INSERT_ID()
php 在Shopkeeper主题中为XL WooCommerce Sales Trigger插件更改WooCommerce单一产品位置