8

I have a QML ListView where the delegate loads it's component from another file. When clicking on an delegate item, I want to update ListView. CurrentIndex and highlight the selected item.

It works, when I explicitly set the id of the ListView. However since I want to use the delegate's Component also for other ListViews, I'm stuggeling to find a generic way how to access ListView.currentIndex from within a delegate Component.

Here is the Code:

main.qml

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2

ApplicationWindow {
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible: true

    ListModel {
        id: contactsModel
        ListElement {
            name: "Bill Smith"
        }
        ListElement {
            name: "John Brown"
        }
        ListElement {
            name: "Sam Wise"
        }
    }

    ListView{
        id: contactsView
        anchors.left: parent.left
        anchors.top: parent.top
        width: parent.width
        height: parent.height
        orientation: Qt.Vertical
        spacing: 10
        model: contactsModel
        delegate: Contact{}
    }
}

Contact.qml (Component used by delegate)

import QtQuick 2.0

Component{
    id: contact
    Rectangle{
        width: 200
        height: 50
        color: ListView.isCurrentItem ? "#003366" : "#585858"
        border.color: "gray"
        border.width: 1

        MouseArea{
            anchors.fill: parent
            onClicked: {
                ListView.currentIndex = index; // <---- does not work
                //  contactsView.currentIndex = index; // <---- Works
            }
        }

        Text{
            anchors.centerIn: parent
            color: "white"
            text: name
        }
    }
}

Any help is really appreciated!

2 Answers 2

17

There are two problems here:

To fix them both, first change this:

ListView.currentIndex = index;

to this:

delegate.ListView.view.currentIndex = index;

And then give your delegate an id:

Component {
    id: contact

    Rectangle {
        id: delegate
    // ...
}

This is demonstrated (in part) by the Example Usage section of the documentation:

ListView attaches a number of properties to the root item of the delegate, for example ListView:isCurrentItem. In the following example, the root delegate item can access this attached property directly as ListView.isCurrentItem, while the child contactInfo object must refer to this property as wrapper.ListView.isCurrentItem.

Sign up to request clarification or add additional context in comments.

Comments

4

Use attached property ListView.view:

This attached property holds the view that manages this delegate instance

Small example:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1

Window {
    width: 600
    height: 400
    visible: true

    Component {
        id: listDelegate
        Rectangle {
            height: 30
            width: parent.width
            color:  ListView.isCurrentItem ? "orange" : "white"
            property var view: ListView.view
            property int itemIndex: index
            Text { anchors.centerIn: parent; text: name }
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    view.currentIndex = itemIndex;
                }
            }
        }
    }

    RowLayout {
        anchors.fill: parent
        ListView {
            Layout.minimumWidth: parent.width / 2
            Layout.fillHeight: true
            model: ListModel {
                ListElement {name: "item1.1"}
                ListElement {name: "item1.2"}
                ListElement {name: "item1.3"}
            }
            delegate: listDelegate
        }
        ListView {
            Layout.minimumWidth: parent.width / 2
            Layout.fillHeight: true
            model: ListModel {
                ListElement {name: "item2.1"}
                ListElement {name: "item2.2"}
                ListElement {name: "item2.3"}
            }
            delegate: listDelegate
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.