首先我们来看一段这样的代码:
<Window x:Class="WpfTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTest"
mc:Ignorable="d"
Title="Window1" Height="500" Width="800">
<Window.Resources>
<Style x:Key="b" TargetType="Border">
<Style.Setters>
<Setter Property="Width" Value="200" />
<Setter Property="Height" Value="200" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="Margin" Value="4" />
</Style.Setters>
</Style>
</Window.Resources>
<WrapPanel>
<Border Style="{StaticResource b}" />
<Border Style="{StaticResource b}" />
<Border Style="{StaticResource b}" />
<Border Style="{StaticResource b}" />
</WrapPanel>
</Window>
然后,我想要实现的效果是,当我点击一个Border时,该Border的边框颜色变为红色,如果之前点击过其他Border,则该Border的边框颜色为黑色(相当于变回原来的颜色) .
目前我想到的可行方法是给每个边框绑定一个mouseclick RoutedEvent,让wrappanel监听这个事件。当事件被触发时,让wrappanel遍历它的孩子。如果有一个孩子的名字等于事件源的名字,请更改此边框颜色,并且不要忘记将所有其他孩子设置为黑色。
但是我觉得这种做法有点麻烦。有没有更优雅简单的处理方式?(不要使用mvvm或其他框架)
另外,我尝试了一个想法,就是当点击边框时,将边框的名称赋值给wrappanel的datacontext,然后为边框设置datatrigger。条件是wrappanel的数据上下文与边框的名称相同。但是经过测试,这是不可能的。“value”的值不能是{binding ...}。
您可以使用带有 WrapPanel 的 ListBox 作为
ItemsPanel
和最简单的 ItemContainerStyle
,而不需要所有标准项目状态可视化。
将 DataTrigger 添加到绑定到每个 Border 的 ListBoxItem 容器的
IsSelected
状态的边框样式。您还必须添加透明背景以使边框命中测试可见。
您也可以将 Border 及其 DataTrigger 移动到 ItemContainerStyle 中,但随后您必须将某种数据项添加到 ListBox 的 Items 或 ItemsSource 集合中。
<ListBox>
<ListBox.Resources>
<Style x:Key="b" TargetType="Border">
<Setter Property="Width" Value="200" />
<Setter Property="Height" Value="200" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Margin" Value="4"/>
<Style.Triggers>
<DataTrigger
Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<Border Style="{StaticResource b}" />
<Border Style="{StaticResource b}" />
<Border Style="{StaticResource b}" />
<Border Style="{StaticResource b}" />
</ListBox>