In your example, the check for DbNull would be fine but you first need to check if any data came back first with rdr.Read (so execute the rdr.Read command and it will return false if no rows).
I find often, it somewhat easier to return the data into a data table.
So, then say this code:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim cmd As New SqlCommand("SELECT * FROM tblHotelsA 
                               WHERE ID = @id")
    cmd.Parameters.Add("@id", SqlDbType.Int).Value = txtHotelID.Text
    Dim rstData As DataTable = MyRstP(cmd)
    If rstData.Rows.Count > 0 Then
        With rstData.Rows(0)
            txtFirst.Text = .Item("FirstName")
            txtLast.Text = .Item("LastName")
            txtHotel.Text = .Item("HotelName")
        End With
    Else
        RptNm.Text = "Hotel not found."
    End If
End Sub
Public Function MyRstP(cmdSQL As SqlCommand) As DataTable
    Dim rstData As New DataTable
    Using conn As New SqlConnection(My.Settings.TEST4)
        Using (cmdSQL)
            cmdSQL.Connection = conn
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
        End Using
    End Using
    Return rstData
End Function
And MyRstP can be placed in a standard module, since then you can call that code from anywhere in your application.
Now, if say FirstName, and LastName, and HotelName in above could be null?
Then that will trigger an error. So, you can still of course have a row returned, but a column could still be empty with a null.
In that case, then this code will work if some of the columns are null.
            txtFirst.Text = .Item("FirstName").ToString
            txtLast.Text = .Item("LastName").ToString
            txtHotel.Text = .Item("HotelName").ToString
So, above can save quite a bit of messy code to check for null values, and if any of those columns are null, then an empty string ("") will be placed in those text boxes.
So, I suggest a data table. This works much like a "recordset" from say VBA, or VB5/VB6 days. And you can traverse the data table more then once, and you can even make changes to the row(s), and then send back all row changes in one operation.
So, for pulling of data, and that of writing out data, then data tables can save you quite a bit of code.