@Model.ListProducts[selectedIndex].Price executes on the server and the result is added to the HTML before it is sent out to the client. This means selectedIndex is out of scope because you don't define and use it until it's in the browser.
You can't mix Razor markup with JavaScript. Razor has already done its work long before JavaScript gets hold of it.
Most likely what you want is to use your model to generate your drop down using the price as the value field and the product as the label. You already have everything else wired up; just replace your use of @Model with JavaScript to get the selected option's value instead.
EDIT: An approach I use for an JavaScript people/entity picker is to serialize data I need either as a delimited string or a JSON stringified object and store that as an attribute on the element (or parent). This lets me have multiple instances of the control on the page and use a single jQuery selector and code block to "restore" or read from the data to grab whatever information I need for dynamic display.
For instance:
<div data-serialized-products="@Model.PriceList.ToDataString()">
@Html.DropDownFor(m => ..., new { @class="showPrice"})
</div>
<script type="text/javascript">
$(function() {
$(".showPrice").change(function() {
var $dd = $(this);
//Grab the selected value, then do $dd.parent("div").data("serialized-products")
//to and either string split (for string delimited) or use JSON parse and access
//the property you need to put in the text box. Bonus - you can put your textbox
//target id in another data- attribute so you can repeat this set of controls.
});
});
</script>
You would need to create your ToDataString() to either return a concatenated string or a JSON stringified string. Your JavaScript function would need a matching JSON parse or delimited string split to access the value. As long as your object isn't very big (and serialize only the property/properties you need) then this should be a useful approach.
$('option:selected').index()