【问题标题】:Update WPF CheckBox in ListVIew from Enabled to Disabled When Clicked, INotify not working单击时将 ListVIew 中的 WPF CheckBox 从启用更新为禁用,INotify 不起作用
【发布时间】:2016-03-18 11:57:50
【问题描述】:

我有一个 ListView,它在下面显示 CheckBoxes XAML 的列表。 Checkbox 是一个自定义类,代码如下。 Checkbox 的初始状态设置正确。但是,当单击复选框时,它应该被禁用(IsEnabled = False),但这并没有发生,尽管在自定义类中实现了如下所示的 INotify 代码(尽管我怀疑错误在这里某处,或者XAML 标记错误)。我什至尝试强制对 Click 事件进行绑定更新,但没有帮助,代码如下。有人可以帮忙吗?

编辑:我刚刚意识到解释可能有点混乱。以下是应该发生的情况:1) 自定义 Checkbox 显示初始值(这部分正在工作),2) 用户单击 Checkbox,3) Click 事件应该触发并更新 IsChecked 属性(看起来这发生在调试器中查看属性时),4)IsEnabled 属性切换为 False 并禁用控件(此操作失败)。

XAML:

<DataTemplate>
<CheckBox Content="test" 
    ToolTip="test"
    IsThreeState="False"
    x:Name="myCheckBox"
    Click="MyClickEvent_OnClicked"
    IsChecked="{Binding outIsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>

自定义复选框:

Public Class MyCustomCheckBox
    Inherits CheckBox
    Implements INotifyPropertyChanged

    Public Property outIsChecked As Boolean
        Get
            Return Me.IsChecked
        End Get
        Set(valueChecked As Boolean)
            If valueChecked <> Me.IsChecked Then
                Me.IsChecked = valueChecked
                'NotifyPropertyChanged("IsChecked")
                'OnPropertyChanged(New PropertyChangedEventArgs("IsChecked"))
                RaisePropertyChanged("IsChecked")
            End If

        End Set
    End Property

    Public Sub New()
    End Sub

    Public Sub New(ByVal inIsChecked As Boolean)
        outIsChecked = inIsChecked
    End Sub

    Public Event PropertyChanged As PropertyChangedEventHandler _
    Implements INotifyPropertyChanged.PropertyChanged

    Protected Sub RaisePropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

End Class

点击事件:

Public Sub MyClickEvent_OnClicked(sender As Object, e As RoutedEventArgs)

    Dim cbx1 As ChordPattern = CType(checkboxList(keyIndexes(0)), MyCustomCheckBox)
    cbx1.outIsChecked = False
    cbx1.IsEnabled = False

    'cbx1.GetBindingExpression(MyCustomCheckBox.IsEnabledProperty).UpdateTarget()
End Sub

【问题讨论】:

  • 我认为行“Dim cbx1 As ChordPattern = CType(checkboxList(keyIndexes(0)), MyCustomCheckBox)”的问题。尝试将其替换为“Dim cbx1 As MyCustomCheckBox = CType(sender, MyCustomCheckBox)”

标签: wpf xaml checkbox binding inotifypropertychanged


【解决方案1】:

您可以覆盖 Style 并为“Click”事件添加特殊的 EventTrigger,这会将 IsEnabled 属性设置为 false。

<CheckBox>
    <CheckBox.Style>
        <Style TargetType="CheckBox">
            <Style.Triggers>
                <EventTrigger RoutedEvent="Click">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsEnabled">
                                    <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False" />
                                </BooleanAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </CheckBox.Style>                       
</CheckBox>

【讨论】:

  • 感谢您的回答。这是一个非常酷的想法,但它不适用于这个项目,因为在代码隐藏中还有其他事情需要完成(例如,其他代码的设置取决于哪个复选框是事件的发送者,我还想根据取消/选中的复选框为其他控件设置其他自定义属性)。
  • 我的应用程序正常运行,但有一个新问题。你可以在这里看到它:stackoverflow.com/questions/34251149/…
【解决方案2】:

在您的情况下,最好摆脱与 outIsChecked 属性的绑定,并在单击事件处理程序中直接使用 CheckBox.IsEnabled。

类似的东西:

Public Sub MyClickEvent_OnClicked(sender As Object, e As RoutedEventArgs)

    Dim cbx1 As ChordPattern = CType(checkboxList(keyIndexes(0)), MyCustomCheckBox)
    cbx1.IsChecked = False
    cbx1.IsEnabled = False    
End Sub

并且去掉绑定,因为这里好像没什么用:

<DataTemplate>
<CheckBox Content="test" 
    ToolTip="test"
    IsThreeState="False"
    x:Name="myCheckBox"
    Click="MyClickEvent_OnClicked"/>
</DataTemplate>

【讨论】:

  • 您的第一个建议做到了。我有两个属性试图提供(真的)相同的信息,并且让自己对尝试管理它们感到困惑。一旦我消除了自定义的(outIsChecked),它就开始正常工作。再次感谢。
  • 对于您之前关于我的 ComboBoxes 的观点,现在我想考虑动态填充它们。在这里查看我的问题:stackoverflow.com/questions/34251149/…
  • 我建议使用视图模型和数据绑定,并以任何方式避免直接事件处理程序。当您在代码中实现业务逻辑并将其与 UI 对象混合时,很容易卡在 WPF 中。经验法则是 *.xaml.cs 文件中不应有任何内容。甚至 View Model 实例化和附加到 DataContext 也可以在 xaml 中完成。我坚信我昨天的代码 (stackoverflow.com/a/34238161/5574010) 是一个很好的起点。在 ViewModel 级别实现您的需求确实比在后面的代码中更简单。
猜你喜欢
  • 2015-12-05
  • 2011-05-31
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 2018-04-10
  • 2013-04-12
  • 2018-01-08
相关资源
最近更新 更多