Checkbox commanding, check - OK, Uncheck NOT ok, how do i bind the uncheck command?

Topics: Prism v2 - Silverlight 4, Prism v4 - Silverlight 4
Oct 21, 2010 at 10:32 AM

Hi,
I'm having problems attaching an uncheck command to a checkbox. Or more correct, I do not know how to code it. Here's my code for the check command, how should it look to get uncheck also working?

View:

<CheckBox commands:Checked.Command="{Binding CheckCommand}"
    IsChecked="False"></CheckBox>


 

ViewModel:

Private _CheckCommand As DelegateCommand(Of Object)

    CheckCommand = New DelegateCommand(Of Object)(AddressOf Checked)

    Private Sub Checked(ByVal parameter As Object)

    End Sub

 

Command:

Public Class ToggleCheckedCommandBehaviour
        Inherits CommandBehaviorBase(Of CheckBox)

        Public Sub New(ByVal checkableObject As CheckBox)
            MyBase.New(checkableObject)
            AddHandler checkableObject.Checked, AddressOf checkableObject_Checked
        End Sub

        Private Sub checkableObject_Checked(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)
            CommandParameter = TargetObject.Name
            ExecuteCommand()
        End Sub
    End Class

    Public NotInheritable Class Checked

        Private Sub New()
        End Sub

        Private Shared ReadOnly SelectedCommandBehaviorProperty As DependencyProperty = _
        DependencyProperty.RegisterAttached("SelectedCommandBehavior", _
                                            GetType(ToggleCheckedCommandBehaviour), _
                                            GetType(Checked), _
                                            Nothing)

        Private Shared ReadOnly CommandProperty As DependencyProperty = _
        DependencyProperty.RegisterAttached("Command", _
                                            GetType(ICommand), _
                                            GetType(Checked), _
                                            New PropertyMetadata(AddressOf OnSetCommandCallback))


        Public Shared Sub SetCommand(ByVal CheckBox As CheckBox, ByVal command As ICommand)
            CheckBox.SetValue(CommandProperty, command)
        End Sub

        Public Shared Function GetCommand(ByVal CheckBox As CheckBox) As ICommand
            Return TryCast(CheckBox.GetValue(CommandProperty), ICommand)
        End Function

        Private Shared Sub OnSetCommandCallback(ByVal dependencyObject As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
            Dim CheckBox = TryCast(dependencyObject, CheckBox)
            If Not CheckBox Is Nothing Then
                Dim behavior = GetOrCreateBehavior(CheckBox)
                behavior.Command = TryCast(e.NewValue, ICommand)
            End If
        End Sub

        Private Shared Function GetOrCreateBehavior(ByVal CheckBox As CheckBox) As ToggleCheckedCommandBehaviour
            Dim behavior = TryCast(CheckBox.GetValue(SelectedCommandBehaviorProperty), ToggleCheckedCommandBehaviour)
            If behavior Is Nothing Then
                behavior = New ToggleCheckedCommandBehaviour(CheckBox)
                CheckBox.SetValue(SelectedCommandBehaviorProperty, behavior)
            End If
            Return behavior
        End Function

    End Class
    End Namespace

 

As mentioned the check command works fine, and the command and method connected to it gets fired, what do I need to do to get the uncheck also working?
For info I'm using PRISM v2, CAL, MVVM and SL4 - in VB.NET

Oct 22, 2010 at 2:34 PM

Hi,

The fact that the Checked command is working correctly means that the attached behavior was correctly implemented. That said, the behavior only monitors a single event which you specify in this line:

AddHandler checkableObject.Checked, AddressOf checkableObject_Checked

Thus, you are subscribing to the Checked event of the Checkbox control. As you want to have control of the Checkbox being unchecked, you simply need to create another command behavior using the Unchecked event. This assumes that you want a different command executed when the button is checked/unchecked. But If you use the same command, then binding to the Command property should suffice.

Hope this helps.

Fernando Antivero
http://blogs.southworks.net/fantivero

Oct 25, 2010 at 7:11 AM

 

 

 

 

 

Thanx fantivero, you put me on the right path. I change my code to monitor the click event instead, that way I'm able to catch both unched/check event and by passing the TargetObject as commandparameter back to my viewmodel I can do various stuff with IsChecked bool to determine wheter it's a "check click" or "uncheck click". 

AddHandler checkableObject.Click, AddressOf checkableObject_Click

Private Sub checkableObject_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs
 CommandParameter = TargetObject
 ExecuteCommand()
End Sub

When I detect a click, I'm displaying a view within a region (ItemsControl) in another view. So if I check 5 checkboxes the mainview will hold 5 detailviews in its ItemsControl.. I add the views like this: 

(but how can I remove the views on uncheck?)

 Dim basketRegion = _RegionManager.Regions("basketRegion")
        Dim view = _Container.Resolve(Of basketDetailsView)()
        Dim viewmodel = _Container.Resolve(Of basketDetailsViewModel)()

        viewmodel.basketName = basketName
        view.ApplyModel(viewmodel)
        basketRegion.Add(view)

Oct 25, 2010 at 2:07 PM

Hi,

Based on the code that you shared you are using View Injection for adding your views to the region. So, if you want to remove a view from a region, you could use the Remove method in the Region class.

But before removing the views, you must add your views indicating a view name for each one. So your code might be similar to the following:

basketRegion.Add(view, "YourViewName")

Once you added your views using the aforementioned approach, you will be able to remove these views using the following code (pseudo-code):

Dim basketRegion = _RegionManager.Regions("basketRegion")
Dim yourView = basketRegion.GetView("YourViewName")
basketRegion.Remove(yourView)

If you need more guidance on this topic, you could also check the UIComposition Quickstart, since it provides the recommended approaches for similar scenarios.

Hope this helps.

Fernando Antivero
http://blogs.southworks.net/fantivero

Oct 26, 2010 at 9:17 AM

That works like a charm, thank you very much! :)

Please see my latest problem at this thread: http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=232334

:)