You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 12:48:10