WPF自定义日历:如何实现日期而非ListBox月份项的选中功能
解决方案
你的问题核心是外层月份ListBox的Item捕获了内层日期ListBox的点击事件,导致点击日期时可能触发外层Item的选中。以下是两种直接解决的方式:
方式一:外层改用ItemsControl(推荐)
因为你不需要选中月份,只是展示月份列表,用ItemsControl替代外层的ListBox即可彻底避免外层选中问题——它没有选中机制,也不会捕获内层的点击事件:
修改原XAML中外层的ListBox代码:
<!-- 把外层ListBox改成ItemsControl --> <ItemsControl Grid.Row="1" ItemsSource="{Binding ListMonths}"> <ItemsControl.Style> <Style TargetType="{x:Type ItemsControl}"> <Setter Property="Background" Value="Transparent"/> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <UniformGrid Columns="3"/> </ItemsPanelTemplate> </Setter.Value> </Setter> </Style> </ItemsControl.Style> <ItemsControl.ItemTemplate> <DataTemplate> <Grid> <ListBox Grid.Row="1" ItemsSource="{Binding ListDays}" Style="{StaticResource monthTemplate}"/> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
方式二:禁用外层ListBoxItem的点击响应
如果你必须保留外层ListBox,给外层ListBox添加ItemContainerStyle,设置IsHitTestVisible="False",让外层Item不响应鼠标点击:
<ListBox Grid.Row="1" ItemsSource="{Binding ListMonths}"> <ListBox.Style> <Style TargetType="{x:Type ListBox}"> <Setter Property="Background" Value="Transparent"/> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <UniformGrid Columns="3"/> </ItemsPanelTemplate> </Setter.Value> </Setter> <!-- 添加ItemContainerStyle,禁用外层Item的点击 --> <Setter Property="ItemContainerStyle"> <Setter.Value> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="IsHitTestVisible" Value="False"/> <Setter Property="Background" Value="Transparent"/> </Style> </Setter.Value> </Setter> </Style> </ListBox.Style> <ListBox.ItemTemplate> <DataTemplate> <Grid> <ListBox Grid.Row="1" ItemsSource="{Binding ListDays}" Style="{StaticResource monthTemplate}"/> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
额外优化:确保日期ListBoxItem的选中状态可见
你可以在LBXI.DAY样式中添加选中状态触发器,让选中的日期更明显:
<Style TargetType="{x:Type ListBoxItem}" x:Key="LBXI.DAY"> <!-- 原有Setter保留 --> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <Grid> <!-- 原有元素保留 --> <Border x:Name="ItemBorder" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Padding="{TemplateBinding Padding}"> <!-- 原有Border.Style保留 --> </Border> <TextBlock Text="{Binding Day}" Opacity="1" FontSize="12" Margin="2,2,0,0" FontWeight="DemiBold"/> </Grid> <!-- 添加选中状态触发器 --> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter TargetName="ItemBorder" Property="BorderBrush" Value="#2196F3"/> <Setter TargetName="ItemBorder" Property="Background" Value="#E3F2FD"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
内容的提问来源于stack exchange,提问作者Siegfried.V
相关产品推荐
相关产品推荐

