manejo de punteros C#

Publicado por Lucas
hace 11 años

<p>Hola. Hace un tiempo comencé a desarrollar un entorno de desarrollo integrado para nasm llamado edigio. Como una especie de pruebas y ejercitación con c# lo comencé y luego de iniciar con un richtextbox para el editor seguí con otro de sharpdevelop, pero como no me convenció termino utilizando al famoso scintilla.</p>

<p>El programa usa pestañas, como cualquier edi (ide); su contenedor es llamado contenedor_de_pestanias (TabControl).</p>

<p>Hay varias opciónes que me dieron una serie de dudas, sobretodo la de modificar por punteros el contenido de un editor específico. En el contexto del proyecto, hay un botón que se encarga de limpiar todo el código por completo. Mi lógica de nivel medio dice que genere un puntero a ScintillaNet (la clase del editor de textos) y le asigne la dirección del editor que actualmente tiene el foco...</p>

<p>(Nota: Scintilla para edigio: ScintillaNet)</p>

<pre class="prettyprint"> Scintilla_para_edigio* puntero_al_editor_actual = &(Scintilla_para_edigio)contenedor_de_pestanias.TabPages[contenedor_de_pestanias.SelectedIndex].Controls[0];</pre>

<p>entonces muy fácilmente para darle funcionalidad a ese botón haría:</p>

<pre class="prettyprint"> (*puntero_al_editor_actual).Text = "";</pre>

<p>y caso cerrado.</p>

<p>Incluso permitiéndo código no seguro y utilizando 'unsafe' en el código da:</p>

<p>1.- No se puede adquirir la dirección, obtener el tamaño ni declarar un puntero a un tipo administrado ('Edigio.Scintilla_para_edigio')</p>

<p>2.- No se puede adquirir la dirección de la expresión dada.</p>

<p>Más allá de si es scintilla o no, ¿cómo podría hacer para modificar una propiedad de un objeto de una clase que está representado por su clase base (Control) modificando o no por punteros, y sin declarar objetos locales los cuales se pseudodestruyen al final del método? P ej modificar la propiedad text de un textbox que se encuentra en una pestaña de una colección de pestañas bajo un contenedor de pestañas y de clase Control.</p>

scintilla &* punteros c#
Respuesta de Cristian Olaz
hace 11 años

<p>Hola Lucas, cómo va todo?</p>

<p>Mira, yo creo que no te conviene tratar de utilizar un puntero hacia un control dentro del TabControl, sabiendo también que esos controles aparecen y desaparecen constantemente cuando un usuario abre o cierra un documento. Además de que podés utilizar una variable normal que guarde una referencia hacia ese elemento y sería un poco menos engorroso.</p>

<p>De cualquier forma, me parece que lo importante está al momento de agregar ese controlador a la nueva pestaña. No sé bien como estarás manejando esto en el resto de tu código. Pero posiblemente en algún lugar el usuario puede abrir un documento existente, o crear uno nuevo desde algún botón o menu.</p>

<p>En este momento, vos creas una nueva pestaña y agregás el control que luego querés modificar, Scintilla, textbox, etc. Pero lo importante es que al momento de agregarlo le asignes un nombre. Algo así:</p>

<pre class="prettyprint"> private void btnNuevoArchivo_Click(object sender, EventArgs e) { TabPage nueva_pestania = new TabPage(); TextBox nuevo_textbox = new TextBox(); nuevo_textbox.Name = "textbox"; // Le asignas un nombre nueva_pestania.Controls.Add( nuevo_textbox ); contenedor_de_pestanias.TabPages.Add( nueva_pestania ); }</pre>

<p>Ahora, al momento de ejecutar alguna acción como "limpiar" sobre ese objeto ( en este caso un textbox ) simplemente harías lo siguiente:</p>

<pre class="prettyprint"> contenedor_de_pestanias.TabPages[ contenedor_de_pestanias.SelectedIndex ].Controls[ "textbox" ].Text = "Un nuevo texto en este objeto";</pre>

<p>Pero si tu intención sigue siendo retener ese elemento en una variable podés hacer algo así. Primero declararías esa variable en tu clase.</p>

<pre class="prettyprint"> private TextBox textbox;</pre>

<p>Luego le asignas el objeto que está dentro de la pestaña actual de la siguiente forma.</p>

<pre class="prettyprint"> textbox = (TextBox) contenedor_de_pestanias.TabPages[contenedor_de_pestanias.SelectedIndex].Controls["textbox"]; </pre>

<p>Y por último podés utilizar esta variable en algún otro lugar, por ejemplo en otro método:</p>

<pre class="prettyprint"> public void otro_metodo() { textbox.Text = "Nuevo texto para este objeto"; }</pre>

<p>Espero que te sirva, o que se acerque a lo que necesitás!</p>

<p>Un saludo!!</p>

<p> </p>

<p><strong>Edito:</strong></p>

<p>Genial! Me alegra que te haya servido Lucas! Nos vemos luego, un saludo! ;)</p>

Respuesta de Lucas
hace 11 años

<p>Gracias Cristian por responder mi pregunta.</p>

<p>La que me sirvió fué:</p>

<blockquote> <p>Ahora, al momento de ejecutar alguna acción como "limpiar" sobre ese objeto ( en este caso un textbox ) simplemente harías lo siguiente:</p>

<pre class="prettyprint"> contenedor_de_pestanias.TabPages[ contenedor_de_pestanias.SelectedIndex ].Controls[ "textbox" ].Text = "Un nuevo texto en este objeto";</pre>

<p> </p> </blockquote>

<p>Mi problema principal era que no conocía esa funcionalidad que al asignar a un nuevo objeto también se asignaba su dirección, como un puntero indireccionado. Pensaba que ese objeto era local al método y que se destruía como sucedía en las funciónes de c, o como seguramente, en los métodos estáticos, es decir, manipulando ese objeto no sería útil porque no ejercería modificaciónes en el editor.</p>

<p> </p>

<p>En fin, realmente muchas gracias por tomarte el tiempo. Nos vemos en futuras preguntas :)</p>