Search code examples
c#wpfdatagridwpfdatagridcaliburn.micro

Caliburn.Micro disable default click event for ItemsControl


I have a ViewModel which inherits from Conductor<T>.Collection.OneActive. In the View I bound a DataGrid to the Items property and a ContentControl to ActiveItem.

<ContentControl x:Name="ActiveItem" DockPanel.Dock="Top"/>
    <DataGrid x:Name="Items" AutoGenerateColumns="False" SelectionMode="Single" DockPanel.Dock="Top"
              cal:Message.Attach="[Event MouseDoubleClick] = [Action test]">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding CountryCode}" Width="10*"/>
            <DataGridTextColumn Binding="{Binding Country}" Width="90*" />
        </DataGrid.Columns>
    </DataGrid>
</ContentControl>

It's working fine, except one thing: I want to activate the DetailsViewModel when one of the Grid's row was DoubleClicked. My void test() method gets invoked nicely, but I can not disable the Click method.

Any suggestion?

EDIT

Maybe i was not clear enough. My problem is the default behavior of the Conductor<T>. It should not activate the details screen for one left click but for double.

EDIT 2

By Nkosi's help finally figured out some workaround: Simply changed ContentControl binding from ActiveItem to ActiveScreen.

<ContentControl x:Name="ActiveScreen" DockPanel.Dock="Top"/>

In the ViewModel created the ActiveScreen property:

private T mActiveScreen;
public T ActiveScreen
{
    get { return mActiveScreen; }
    set
    {
        mActiveScreen = value;
        NotifyOfPropertyChange(() => ActiveScreen);
    }
}

In the bound method for MouseDoubleClick you just have to set ActiveScreen to ActiveItem.

    public void test()
    {
        ActiveScreen = ActiveItem;
    }

Solution

  • Caliburn has an action guard feature where Can{MethodName} acts as a guard for the action to be invoked. It can be either a property or another method, once it follows the convention.

    So given

    public void test() { ... }
    

    its guard would look like

    public bool Cantest {
        get { return //..what ever is the condition needed to allow/disable action
    }
    

    or

    public bool Cantest() {
        return //..what ever is the condition needed to allow/disable action
    }
    

    Caliburn documentation - All About Actions

    Another important feature to note is Action guards. When a handler is found for the “SayHello” message, it will check to see if that class also has either a property or a method named “CanSayHello.” If you have a guard property and your class implements INotifyPropertyChanged, then the framework will observe changes in that property and re-evaluate the guard accordingly.