ときにプログラムで追加TemplateFieldでの制御は、そのIDプロパティのセットを持っているのですか?
-
22-08-2019 - |
質問
私は、動的にカスタムGridViewコントロールに追加されTemplateFieldを持っています。
void ITemplate.InstantiateIn(System.Web.UI.Control container)
{
switch (_templateType)
{
case ListItemType.Header:
if (this.ParentGridView.ShowDeleteHeaderImage)
{
Image hImg = new Image();
hImg.ImageUrl = this.ParentGridView.DeleteHeaderImageUrl;
hImg.AlternateText = "Mark for Deletion";
container.Controls.Add(hImg);
}
else
{
Label l = new Label();
l.Text = "Del";
container.Controls.Add(l);
}
break;
case ListItemType.Item:
container.Controls.Add(new CheckBox());
break;
case ListItemType.EditItem:
break;
case ListItemType.Footer:
QLImageButton deleteButton = new QLImageButton();
deleteButton.Settings.ImageId = "cmdQLGVDelete";
deleteButton.Settings.ImageUrl = this.ParentGridView.DeleteImageUrl;
deleteButton.CommandName = "Delete";
container.Controls.Add(deleteButton);
break;
}
}
グリッドコマンド(挿入/更新/削除)に応答して、GetRowControlsと呼ばれる方法がどの反復特定gridrowの列を介して呼び出され、辞書にそのコントロールのそれぞれを追加します。
Dictionary<string, WebControl> GetRowControls(GridViewRow row)
...
rowControls.Add(ctrl.ID, (WebControl)ctrl);
...
これはテンプレートのフィールドと宣言を追加連結コントロールの両方で正常に動作だけでなく、動的な非テンプレートフィールドをプログラム的に追加しました。
しかしながらctrl.IDは常にnullであるため、上記のステートメントは、例外をスロー動的に追加された制御がTemplateField制御されます。
私はVS 2005すなわちで即時ウィンドウで変数を調べたとき?CTRL、ctrl.IDが値を一覧表示することを見つけたので私はリフレクターでこれに見てきました。私は以来、これが原因でイミディエイトウィンドウに?Ctrlキーをリストであることを確立してきた、proprtyのクライアントIDが呼び出され、クライアントIDは順番にIDを設定しますEnsureId()を呼び出すされます。
public virtual string ClientID
{
get
{
this.EnsureID();
string uniqueID = this.UniqueID;
if ((uniqueID != null) && (uniqueID.IndexOf(this.IdSeparator) >= 0))
{
return uniqueID.Replace(this.IdSeparator, '_');
}
return uniqueID;
}
}
上記のようにちょうど最初の二つの読み取りが設定するすべての引き金となるものの - 。だから私は、クライアントID、ユニークIDとIDがすべてNULLであることを仮定していますまたのNamingContainerがnullでないことに注意してください。これは、設定されています。
だから、このための回避策は、すなわちヌルので、単にctrl.ClientIDを読めば== ctrl.IDをチェックする非常に簡単です。そして、時間が賢明な私は本当に上リグルを取得するために持っているので、私はやったのthats。しかし、私はまだ、誰もが彼らの頭の上からそれを知っていれば答えに興味があります。
なぜ他のコントロールとは異なる時刻に設定動的に追加TemplateFieldの子コントロールのID値は、ある
解決
これは、彼らが異なる挙動を示すことはありませんが、宣言コントロールを追加するときには、ほとんど常に、あなたはすぐにIDを設定します。 (それはIDがいっぱいになるだろうので、そのクライアントIDを表示しないように注意してください)ページにノーとIDとラベルを追加してみてくださいとコントロールコレクションを参照し、そのIDをチェックし、それはnullになります。
<asp:Label runat="server">something</asp:Label>
また、あなたがそのようにそれを実行する場合は、IDなしでスパンを取得することに注意します。
他のヒント
フレディは正しいです。
あなたはInstantiateInメソッド内でIDを設定するための責任があります。そして、それは特に指定しない場合は、それらを自動生成CLIENTID理にかなっています。
宣言型のコントロールは、ページの編集中にページビルダーによって割り当てられた自分のIDを取得します。
:あなたは「一時ASP.NET Filesフォルダ」で生成された一時は.csファイルの一つを見ていた場合、あなたはこのような何か(プラグマを剥離)を見つけるだろう//creating a template field, where CopiledBindableTemplateBuilder is the ITemplate
//and its InstantiateIn = @__BuildControl__control9
@__ctrl.ItemTemplate = new System.Web.UI.CompiledBindableTemplateBuilder(
new System.Web.UI.BuildTemplateMethod(this.@__BuildControl__control9),
new System.Web.UI.ExtractTemplateValuesMethod(this.@__ExtractValues__control9));
//and @__BuildControl__control9 calling @__BuildControlButton1
private global::System.Web.UI.WebControls.Button @__BuildControlButton1()
{
global::System.Web.UI.WebControls.Button @__ctrl;
@__ctrl = new global::System.Web.UI.WebControls.Button();
this.Button1 = @__ctrl;
@__ctrl.ApplyStyleSheetSkin(this);
@__ctrl.ID = "Button1"; //<-- here it gets an ID
@__ctrl.Text = "Button";
return @__ctrl;
}