我正在制作一个纸牌游戏,我希望在玩家的手牌中显示半张牌。我怎么能用ListView或StackPanel做到这一点?以下是我想如何显示玩家手牌的示例。
<Grid Background="Green" >
<Image x:Name="One" Width="100" Height="100" Margin="10,10,250,210"/>
<Image x:Name="Two" Width="100" Height="100" Margin="10,10,210,210"/>
</Grid>
更新
我为ListView的ItemContainerStyle设置了边距并且它有效,但我有另一个问题。 ListView项目的宽度不适合图像,并且有一些间距。我该如何删除它。请参见XAML代码下方的图片。
<ListView Grid.Row="0" Grid.Column="0">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin" Value="0, 0, -80, 0"></Setter>
<Setter Property="Height" Value="100"></Setter>
<Setter Property="Width" Value="100"></Setter>
</Style>
</ListView.ItemContainerStyle>
<Image x:Name="One" MaxWidth="100" Height="100" />
<Image x:Name="Two" MaxWidth="100" Height="100" />
</ListView>
答案 0 :(得分:14)
我会在列表中使用Canvas,并将您的卡绘制到画布上,因为画布中绘制的内容不会被剪裁,而是通过画布ZIndex等进行管理。
根据所需的间距调整画布大小,并使内容过大。我还建议在使用列表框和使用模板时绑定到Items-source。
顺便说一下,我使用solidColorBrushes定义我的卡片,所以我可以绘制矩形,用你的图像源替换它。我已经在资源中定义了我的源代码,但实际上它将绑定到ObservableCollection(Say,PlayersCurrentHand等):
<UserControl.Resources>
<x:Array Type="{x:Type SolidColorBrush}" x:Key="Cards">
<SolidColorBrush Color="Blue"/>
<SolidColorBrush Color="Red"/>
<SolidColorBrush Color="White"/>
<SolidColorBrush Color="White"/>
<SolidColorBrush Color="White"/>
<SolidColorBrush Color="White"/>
</x:Array>
</UserControl.Resources>
现在,我认为您正在使用ListBox,因为您想支持选择?如果是这样,WPF突出显示列表框项的方式会搞乱这种重叠,所以我们需要替换它。如果您不想选择,只需使用itemsControl即可跳过所有选择内容。
这是我们的基本列表框:
<ListView ItemsSource="{StaticResource Cards}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="112,98,-325,-25" Width="513" Height="227">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1">
<Rectangle Fill="{Binding}" Width="60" Height="100"/>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
这给了我们这个:
现在,我们希望在画布中绘制所有列表项,所以让我们定义ItemContainerStyle:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<ContentPresenter />
</Canvas>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
了解我们如何将画布宽度设置为15?这定义了我们卡片的间距。所有的画布都以15的间隔堆叠。但是,我们在DateTemplate中绘制的矩形宽度为60,因此这些矩形向右溢出。
我们已经覆盖了凌乱的标准选择和突出样式。但是,我们不知道突出显示和选择了什么,所以让我们重新添加一些功能。我们还可以添加阴影等内容:
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<Rectangle x:Name="Highlight" Width="60" Height="5" Canvas.Top="105"/>
<Rectangle Fill="#50000000" Width="60" Height="100" Margin="5,0,-5,0"/>
<ContentPresenter />
</Canvas>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Highlight" Property="Fill" Value="Yellow"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="99"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
现在我们有了这个:
注意,gif没有完全正确地进行选择。如果没有一些代码,我认为宽度问题很难修复。一种选择是制作一个IValueConverter,它根据卡片列表计算宽度,并将其绑定到Listview的Width属性。
修改强>
找到解决尺寸问题的方法!填充!当然。但是,我发现滚动查看器甚至剪辑它包含的画布(如果你考虑它就有意义)但是我们把所有的努力都隐藏了:
因此,您必须通过手动设置ControlTemplate来覆盖滚动查看器功能:
<ListBox.Template>
<ControlTemplate>
<Border Padding="5,25,55,15" BorderBrush="Gray" BorderThickness="1">
<ItemsPresenter />
</Border>
</ControlTemplate>
</ListBox.Template>
所以现在padding占了最后一张牌的额外50张。
总代码,有一些更多的视觉调整:
<ListView ItemsSource="{StaticResource Cards}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20" BorderBrush="Black">
<ListBox.Template>
<ControlTemplate>
<Border Padding="5,25,55,15" BorderBrush="Gray" BorderThickness="1">
<ItemsPresenter />
</Border>
</ControlTemplate>
</ListBox.Template>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" ClipToBounds="False" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<Rectangle x:Name="Highlight" Width="60" Height="5" Canvas.Top="105"/>
<ContentPresenter x:Name="CardPresenter"/>
</Canvas>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="99"/>
<Setter TargetName="CardPresenter" Property="Canvas.Top" Value="-5"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Highlight" Property="Fill" Value="Yellow"/>
<Setter TargetName="CardPresenter" Property="Canvas.Top" Value="-20"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Border Background="#60000000" BorderThickness="0" CornerRadius="5" Height="100" Margin="5,0,-5,0"/>
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Background="{Binding}" Width="60" Height="100"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
它非常灵活,很容易添加&#34;坚持&#34;功能。动画将是下一个重要的步骤。
修改2
我现在正在玩。我不确定我是否喜欢跳到前面&#34;功能,如果他们只是偷看会更好。另外,将它们扇出(使用多重绑定):
使用以下模板:
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<Rectangle x:Name="Highlight" Width="60" Height="5" Canvas.Top="105"/>
<ContentPresenter x:Name="CardPresenter">
<ContentPresenter.RenderTransform>
<TransformGroup>
<TranslateTransform x:Name="TranslateTransformHighlight"/>
<RotateTransform x:Name="RotateTransformHighlight" CenterY="100"/>
<TranslateTransform x:Name="TranslateTransformSelect"/>
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
</Canvas>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformHighlight" Duration="0:0:0.200" To="-5" Storyboard.TargetProperty="Y" />
<DoubleAnimation Storyboard.TargetName="RotateTransformHighlight" Duration="0:0:0.200" To="-5" Storyboard.TargetProperty="Angle" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformHighlight" Duration="0:0:0.200" To="0" Storyboard.TargetProperty="Y" />
<DoubleAnimation Storyboard.TargetName="RotateTransformHighlight" Duration="0:0:0.200" To="0" Storyboard.TargetProperty="Angle" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Highlight" Property="Fill" Value="Yellow"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformSelect" Duration="0:0:0.200" To="-15" Storyboard.TargetProperty="Y" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformSelect" Duration="0:0:0.200" To="0" Storyboard.TargetProperty="Y" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>