A quick solution is to use viewstate to store and retrieve the property value, but i dont advise you use it without double checking if it is absolutely necessary.
public string L1Subject
{
get { return ViewState["Subject"]!=null?ViewState["Subject"].ToString():null;}
set { ViewState["Subject"]=value; }
}
Also what you are doing inside the property doesnt make sense, you are setting the value of Subject1 by passing it as an OUT parameter to the function
populate("PopulateL2Subjects", DDLSubL2, DDLSubL1, out Subject1)
again you are using
this.L1Subject = Subject1;
through which you are setting the value of Subject1 again
set { Subject1 = Subject1 != null ? Subject1 : null; }
Also the logic you have used inside the set area of property is kinda funny i should say(sorry), you have checked if Subject1 is null and if null you set it with null else you set it again with its own value!!! that means 'your set block does nothing' and it wouldnt make any difference if you left your set block empty( set { } ) provided you are only doing what you are doing now inside it.
Feel free to correct me if i am wrong.