WPF DatePicker的IsEnabled属性未改变外观

6
我认为在工具包中的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;
}

你找到解决这个问题的方法了吗? - Thomas Levesque
这在2010年2月的WPF Toolkit中没有固定。我有那个版本,它的功能与他描述的完全相同。当在XAML中禁用控件时,它将无法在运行时启用。 - user387197
不,我只能说它发生在我的台式机上,但是没有发生在我的笔记本电脑上。我前几天才注意到这一点,所以并不是所有的机器都有这个问题。 - Jonathan
我可以确认我也能够重现这个问题。虽然我还没有测试过.NET 4.0中发布的DatePicker,但我认为它不会有这个问题,尽管可能存在。 - jpierson
5个回答

7
我通过在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);
}

4

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

好消息是,微软表示在WPFToolkit的2010年2月版本中已经解决了这个问题。确实如此。

坏消息是,尽管将DatePicker的IsEnabled值设置为“True”会使DatePicker启用,因此您现在可以单击日历按钮选择日期,但它仍然看起来被禁用。

“Bug”?我说过“bug”吗?

当然没有。

不过您可以通过应用<Style>解决此问题。

以下是一些简单的xaml代码进行演示。

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

这显示了没有样式的DatePicker(在第一行)和具有样式的DatePicker(在第二行)之间的差异。

alt text

两个DatePicker都正确地启用/禁用,但第一行中的DatePicker永远不会看起来像已启用。第二行中的DatePicker使用Style向用户显示其是否已禁用。

请注意,此代码设置了DatePicker控件和其中的DatePickerTextBox部分的Background。

<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年以来,用户一直在抱怨此问题...


在这种情况下它不起作用:例如,当DatePicker的IsEnabled属性绑定到CheckBox.IsChecked时,如果您将CheckBox XAML代码放在DatePicker之前,那么DatePicker将永远保持灰色。如果您将DatePicker放在CheckBox之前,则不会有任何问题,您的解决方案可以正常工作。我很疯狂地想知道它是什么时候发生的。 - Amir Karimi

2
另一种伪造“灰色/禁用”样式的方法是滥用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”错误得到修复。 问题7904 / 问题9641


0

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

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

在第一个选项卡上,日期选择器将正常工作。在第二个选项卡上,它将显示为禁用状态,但您仍然可以打开日历并更改日期。


发布一个用户控件,为我们抽象它怎么样? - Jonathan

-1

这个问题已经在新的WPFToolkit中得到解决。


我们正在使用2009年6月发布的版本。 - Kishore Kumar
2
这是最新的工具包,日期为2010年2月。 - Jonathan
从我的测试来看,即使在2010年2月的版本中,这个问题仍然存在 :( http://wpf.codeplex.com/discussions/209288 - D_Guidi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接