An alternative to using a case would be to write some kind of class to do the mapping, for example:
public sealed class CostsPerWeight
{
    class CostPerWeight
    {
        public int Low;
        public int High;
        public double Cost;
    }
    readonly List<CostPerWeight> costs = new List<CostPerWeight>();
    public CostsPerWeight Add(int low, int high, double result)
    {
        // Error handling omitted for brevity. 
        // Real code should check that low < high and that ranges do not overlap.
        costs.Add(new CostPerWeight { Low = low, High = high, Cost = result } );
        return this;
    }
    public double Cost(int weight)
    {
        // This throws if the weight isn't in the list.
        // If that's not what you want, you'd have to add extra error handling here.
        return costs.First(x => x.Low <= weight && weight <= x.High).Cost;
    }
}
Which you would use like this (I've used doubles instead of strings for the costs for this example, but you can use whatever type you need):
var costs = new CostsPerWeight()
    .Add( 0,  2,  3.69)
    .Add( 3,  4,  4.86)
    .Add( 5,  6,  5.63)
    .Add( 7,  8,  5.98)
    .Add( 9, 10,  6.28)
    .Add(11, 30, 15.72);
double shippingCost = costs.Cost(weight);
If you have a lot of these switch statements in VB, it would be worth considering this approach.
(The advantage of using this instead of a Linq one-liner is simply that it's easier to document and unit test. You could also create a CostsPerWeight class instance and pass it around - useful for decoupling code, dependency-injection and for unit testing.)
It does seem to me that the concept of looking up a cost based on a weight is crying out to be encapsulated in a class, rather than embedded piecemeal in various parts of the code.
Here's a more extended example of CostsPerWeight with more error handling:
public class CostsPerWeight
{
    class CostPerWeight
    {
        public int Low;
        public int High;
        public double Cost;
    }
    readonly List<CostPerWeight> costs = new List<CostPerWeight>();
    double min = double.MaxValue;
    double max = double.MinValue;
    double costForMin;
    public CostsPerWeight Add(int low, int high, double cost)
    {
        if (low > high)
            throw new ArgumentException(nameof(low) + " must be less than " + nameof(high));
        if (cost < 0)
            throw new ArgumentOutOfRangeException(nameof(cost), "cost must be greater than zero");
        costs.Add(new CostPerWeight { Low = low, High = high, Cost = cost } );
        if (low < min)
        {
            min = low;
            costForMin = cost;
        }
        if (high > max)
            max = high;
        return this;
    }
    public double Cost(int weight)
    {
        if (weight < min)
            return costForMin;
        if (weight > max)
            throw new InvalidOperationException($"Weight {weight} is out of range: Must be <= {max}");
        return costs.First(x => x.Low <= weight && weight <= x.High).Cost;
    }
}