WPF DatePicker IsEnabled 属性不改变外观

Posted

技术标签:

【中文标题】WPF DatePicker IsEnabled 属性不改变外观【英文标题】:WPF DatePicker IsEnabled property not changing appearance 【发布时间】:2011-02-07 18:54:31 【问题描述】:

我想我在工具包中发现了DatePicker 的问题,也许你们中的一些专家可以检查一下。

问题在于设置DatePickerIsEnabled 属性时。如果在 XAML 中设置,即使在运行时将 IsEnabled 设置为 true,它也会保持灰色。如果它开始被启用,反之亦然。

这个按钮只是改变了日期选择器的IsEnabled属性,你会看到当它启用时,样式仍然是灰色的。

<Window x:Class="WpfApplication3.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <tk:DatePicker x:Name="txtDate" IsEnabled="False"></tk:DatePicker>
        <Button Height="25" Click="Button_Click"></Button>
    </StackPanel>
</Window>

private void Button_Click(object sender, RoutedEventArgs e)

    txtDate.IsEnabled = !txtDate.IsEnabled;

【问题讨论】:

你找到解决这个问题的方法了吗? 这在 2010 年 2 月发布的 WPF 工具包中没有得到修复。我有那个版本,它的功能与他描述的完全一样。在 XAML 中禁用时,该控件将不会在运行时启用。 不,我只能说它发生在我的台式机上,而不是我的笔记本电脑上,我前几天注意到了这一点,所以它不是在所有机器上。 我可以确认我也能够重现此问题。虽然我还没有测试过 .NET 4.0 中发布的 DatePicker,但我假设它不会有这个问题。 【参考方案1】:

我通过在 IsEnabledChanged 处理程序中明确设置 DatePicker 的视觉样式解决了这个问题:

private void datePicker_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)

    DatePicker datePicker = sender as DatePicker;
    if (datePicker.IsEnabled)
        VisualStateManager.GoToState(datePicker, "Normal", true);
    else
        VisualStateManager.GoToState(datePicker, "Disabled", true);

【讨论】:

【参考方案2】:

你想要好消息还是坏消息?

好消息是,Microsoft 表示此问题已在 2010 年 2 月发布的 WPFToolkit 中得到修复。它有。

坏消息是,虽然将 DatePicker 的 IsEnabled 值设置为“True”启用 DatePicker,所以您现在可以点击日历按钮来选择一个日期,它仍然会看起来被禁用。

“错误”?我说的是“bug”这个词吗?

当然不是。

您可以通过应用&lt;Style&gt; 来解决此问题。

下面是一些简单的 xaml 代码来演示。

它显示两行,每行包含一个 CheckBox 和一个 DatePicker。 当您单击一行中的 CheckBox 时,它应该启用该行中的 DatePicker。

这显示了不带样式的 DatePicker(第一行)和带样式的 DatePicker(第二行)之间的区别。

两个 DatePickers 确实 正确启用/禁用,但第一行中的那个看起来从来没有。第二行中的 DatePicker 使用 Style 向用户显示它被禁用的时间。

注意这段代码如何设置DatePicker 控件和DatePickerTextBox 部分的背景。

<Window x:Class="WPFDatePickerTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wpf="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" 
    xmlns:primitives="clr-namespace:Microsoft.Windows.Controls.Primitives;assembly=WPFToolkit"
    Title="Window1" Height="317" Width="461">
<Window.Resources>
    <Style TargetType="x:Type primitives:DatePickerTextBox">
        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Background" Value="Transparent"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="DatePickerStyle1" TargetType="x:Type wpf:DatePicker">
        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Background" Value="x:Static SystemColors.InactiveBorderBrush"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <StackPanel>
        <WrapPanel>
            <CheckBox Height="16" Name="cbDateOfJoining" Width="120">Date of joining</CheckBox>
            <wpf:DatePicker Height="25" 
                            Name="datePicker1" 
                            Width="140" 
                            IsEnabled="Binding IsChecked, ElementName=cbDateOfJoining" />
        </WrapPanel>
        <WrapPanel>
            <CheckBox Height="16" Name="cbDateOfLeaving" Width="120">Date of leaving</CheckBox>
            <wpf:DatePicker Height="25" 
                            Name="datePicker2" 
                            Width="140" 
                            IsEnabled="Binding IsChecked, ElementName=cbDateOfLeaving"
                            Style="DynamicResource DatePickerStyle1" />
        </WrapPanel>
    </StackPanel>
</Grid>
</Window>

希望有所帮助!

我希望它在下一个 WPFtoolkit 版本中正确得到修复。自 2009 年以来,用户一直在抱怨这个问题...

【讨论】:

Is 在这种情况下不起作用:例如,当 DatePicker IsEnabled 属性绑定到 CheckBox.IsChecked 时,如果您将 CheckBox XAML 代码放在 DatePicker 之前,DatePicker 将永远保持灰色。如果您将 DatePicker 放在 CheckBox 之前,那么您没有任何问题并且您的解决方案有效。想知道它是什么时候发生的,这让我抓狂。【参考方案3】:

另一种伪造“灰色/禁用”样式的方法是滥用 IsHitTestVisible 属性。

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:wpf="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" 
    x:Class="CalendarTest.Window1" 
    x:Name="Window" 
    Title="MainWindow" 
    Width="640" 
    Height="480">
<StackPanel>
    <CheckBox x:Name="IsCalendarEnabled" Content="Is Calendar Enabled" />
    <wpf:DatePicker IsHitTestVisible="Binding ElementName=IsCalendarEnabled, Path=IsChecked">
        <wpf:DatePicker.Style>
            <Style TargetType="x:Type wpf:DatePicker">
                <Style.Triggers>
                    <Trigger Property="IsHitTestVisible" Value="False">
                        <Setter Property="Foreground" Value="#FFB9B9B9" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </wpf:DatePicker.Style>
    </wpf:DatePicker>
</StackPanel>
</Window>

在修复“IsEnabled”错误之前,这只是另一个临时解决方法。 issue 7904 / issue 9641

【讨论】:

【参考方案4】:

有没有人得到过这个问题的答案?我在 2009 年 2 月的版本中遇到了同样的问题。

试试这个。 1/ 使用选项卡控件并在第一个选项卡上放置一个日期选择器,在第二个选项卡上放置一个。 2/ 添加一个按钮,并在单击事件中将两个日期选择器控件的 IsEnabled 属性设置为反向值(因此,如果已启用,则将其禁用,反之亦然)。

在第一个选项卡上,日期选择器会很好。第二次,它会显示为已禁用,但您仍然可以打开日历并更改日期。

【讨论】:

发布一个为我们抽象的用户控件怎么样?【参考方案5】:

这个问题已经在新的 WPFToolkit 中解决了

【讨论】:

我们使用的是 2009 年 6 月发布的版本。 这是最新的工具包,日期为 2010 年 2 月 从我也在 2010 年 2 月发布的测试中发现问题仍然存在 :( wpf.codeplex.com/discussions/209288

以上是关于WPF DatePicker IsEnabled 属性不改变外观的主要内容,如果未能解决你的问题,请参考以下文章

WPF Button isPressed 和 isEnabled 问题

WPF 条件绑定。 Button.IsEnabled 到 SelectedIndex >= 0

C# WPF IsEnabled 使用多个绑定?

WPF 网格与孩子。如何将子 IsEnabled 绑定到父行

WPF XAML 在 IsEnabled 状态下更改图像不透明度

仅在网格(WPF)中为一行添加IsEnabled