Buscar

Ingphillip's-Prog

TODO: WEB!!!

Categoría

.NET

Sobreponer html sobre plug-in de Silverlight!


Hola, amigos me reporto en el blog.

En esta entrada quiero veamos un tema que no es muy cómo a la hora de embeber un plug-in en las páginas ASPX.

Supongamos que en una página de asp.net, tenemos algún tipo de Menu muy sencillo, el cuál debe sobreponerse a todo el contenido de la página (html resultante de la ejecución de una página web aspx), este trabajo se logra con CSS básico, a través de la propiedad z-index, la cual permite sobreponer objetos html unos sobre otros, pero cuando se trabaja con un objeto de Silverlight el problema toma otra proporción.

Lo primero es crear un proyecto de Silverlight en Visual Studio 2010

Veamos, tengo el siguiente código de un Menu de ASP.NET con su respectivo CSS


<style type="text/css">
  #logo
        {
            float: left;
            width: 10.5em;
            background: #CCCCCC;
            padding: 0.5em 0.5em 0.5em 1em;
            margin: 0;
        }
        .primaryStaticMenu
        {
            background-color: transparent;
            float: right;
        }
        .primaryStaticMenuItem
        {
            width: 10em;
            background-color: #f7f2ea;
            border-width: 1px;
            border-color: #efefef #aaab9c #ccc #efefef;
            border-style: solid;
            color: #777777;
            padding: 0.5em 0 0.5em 1em;
        }
        .primaryStaticHover
        {
            color: #800000;
            background: #f0e7d7;
        }
        
        .primaryDynamicMenu
        {
            background-color: #f7f2ea;
            border-bottom: solid 1px #ccc;
        }
        .primaryDynamicMenuItem
        {
            width: 10em;
            background-color: #f7f2ea;
            color: #777;
            padding: 0.5em 0 0.5em 1em;
            border-width: 1px;
            border-color: #f7f2ea #aaab9c #f7f2ea #efefef;
            border-style: solid;
        }
        .primaryDynamicHover
        {
            color: #800000;
            background: #f0e7d7;
        }
        
        .secondaryLevelOne
        {
            background-color: transparent;
            background-repeat: repeat-x;
            margin: 1.5em 0 0 0;
            padding: 5px 0 0 5px;
            width: 12em;
            height: 35px;
        }
        .secondaryLevelTwo
        {
            background: #FAFBFB;
            padding: 5px 0 5px 5px;
        }
        .secondaryStaticHover
        {
            color: #800000;
        }
</style>

<div id="container">
        <asp:Menu ID="menuPrimary" runat="server" DataSourceID="siteSource1" Orientation="Horizontal"
            StaticEnableDefaultPopOutImage="false" StaticDisplayLevels="1" MaximumDynamicDisplayLevels="1">
            <StaticMenuStyle CssClass="primaryStaticMenu" />
            <StaticMenuItemStyle CssClass="primaryStaticMenuItem" />
            <StaticHoverStyle CssClass="primaryStaticHover" />
            <DynamicMenuStyle CssClass="primaryDynamicMenu" />
            <DynamicMenuItemStyle CssClass="primaryDynamicMenuItem" />
            <DynamicHoverStyle CssClass="primaryDynamicHover" />
        </asp:Menu>
    </div>
    <asp:SiteMapDataSource ID="siteSource1" runat="server" ShowStartingNode="false" />

Control de Silverlight

<UserControl x:Class="ZInexProblem.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="50" d:DesignWidth="200" HorizontalAlignment="Left"  >

    <Grid x:Name="LayoutRoot" Background="White">
        <TextBox Foreground="Red" Background="Yellow" TextWrapping="Wrap" HorizontalContentAlignment="Center" FontSize="20" FontFamily="Comic Sans MS" Text="TextBox Especial"></TextBox>
    </Grid>
</UserControl>

Así creamos un control TextBox de Silverlight muy sencillo para hacer las pruebas.

De esta forma el problema consiste en que el plug-in de Silvelright por defecto se va a sobreponer a cualquier tipo de contenido que se cree en la página ASPX, es decir, en este caso el control menu va a quedar solapado bajo la película de silverlight, lo cual nos indicaría un bug(El cual no existe :).

Para solucionar esto debemos hacer lo siguiente:

Como ya algunos sabemos un plug-in de silverlight se carga y referencia a través de un tag object de html.

    <div id="silverlightControlHost">
        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2">
            <param name="source" value="ClientBin/ZInexProblem.xap" />
            <param name="onError" value="onSilverlightError" />
            <param name="background" value="white" />
            <param name="minRuntimeVersion" value="3.0.40818.0" />

            <param name="autoUpgrade" value="true" />
            <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration: none">
                <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight"
                    style="border-style: none" />
            </a>
        </object>
        <iframe id="_sl_historyFrame" style="visibility: hidden; height: 0px; width: 0px;
            border: 0px"></iframe>
    </div>

Bien la primer impresión que nos llevamos luego de ejecutar la aplicación es la siguiente:

Para solucionar este inconveniente, es necesario agregar al tag object de html el atributo.

<param name="windowless" value="true" />

Esto permite que de cierta forma el plug-in se integre con el DOM de html, y así podamos a través del manejo de las propiedades zindex indicar que capa asumira la película respecto al div contendor del objeto menu.

Veamos el código completo de la página ASPX:

<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>ZInexProblem</title>
    <style type="text/css">
        html, body
        {
            height: 100%;
            overflow: auto;
        }
        body
        {
            padding: 0;
            margin: 0;
        }
        #silverlightControlHost
        {
            text-align: left;
            z-index: 0;
        }
        #logo
        {
            float: left;
            width: 10.5em;
            background: #CCCCCC;
            padding: 0.5em 0.5em 0.5em 1em;
            margin: 0;
        }
        .primaryStaticMenu
        {
            background-color: transparent;
            float: right;
        }
        .primaryStaticMenuItem
        {
            width: 10em;
            background-color: #f7f2ea;
            border-width: 1px;
            border-color: #efefef #aaab9c #ccc #efefef;
            border-style: solid;
            color: #777777;
            padding: 0.5em 0 0.5em 1em;
        }
        .primaryStaticHover
        {
            color: #800000;
            background: #f0e7d7;
        }
        
        .primaryDynamicMenu
        {
            background-color: #f7f2ea;
            border-bottom: solid 1px #ccc;
        }
        .primaryDynamicMenuItem
        {
            width: 10em;
            background-color: #f7f2ea;
            color: #777;
            padding: 0.5em 0 0.5em 1em;
            border-width: 1px;
            border-color: #f7f2ea #aaab9c #f7f2ea #efefef;
            border-style: solid;
        }
        .primaryDynamicHover
        {
            color: #800000;
            background: #f0e7d7;
        }
        
        .secondaryLevelOne
        {
            background-color: transparent;
            background-repeat: repeat-x;
            margin: 1.5em 0 0 0;
            padding: 5px 0 0 5px;
            width: 12em;
            height: 35px;
        }
        .secondaryLevelTwo
        {
            background: #FAFBFB;
            padding: 5px 0 5px 5px;
        }
        .secondaryStaticHover
        {
            color: #800000;
        }
    </style>
    <script type="text/javascript" src="Silverlight.js"></script>
    <script type="text/javascript">
        function onSilverlightError(sender, args) {
            var appSource = "";
            if (sender != null && sender != 0) {
                appSource = sender.getHost().Source;
            }

            var errorType = args.ErrorType;
            var iErrorCode = args.ErrorCode;

            if (errorType == "ImageError" || errorType == "MediaError") {
                return;
            }

            var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n";

            errMsg += "Code: " + iErrorCode + "    \n";
            errMsg += "Category: " + errorType + "       \n";
            errMsg += "Message: " + args.ErrorMessage + "     \n";

            if (errorType == "ParserError") {
                errMsg += "File: " + args.xamlFile + "     \n";
                errMsg += "Line: " + args.lineNumber + "     \n";
                errMsg += "Position: " + args.charPosition + "     \n";
            }
            else if (errorType == "RuntimeError") {
                if (args.lineNumber != 0) {
                    errMsg += "Line: " + args.lineNumber + "     \n";
                    errMsg += "Position: " + args.charPosition + "     \n";
                }
                errMsg += "MethodName: " + args.methodName + "     \n";
            }

            throw new Error(errMsg);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server" style="height: 100%">
    <div id="container">
        <asp:Menu ID="menuPrimary" runat="server" DataSourceID="siteSource1" Orientation="Horizontal"
            StaticEnableDefaultPopOutImage="false" StaticDisplayLevels="1" MaximumDynamicDisplayLevels="1">
            <StaticMenuStyle CssClass="primaryStaticMenu" />
            <StaticMenuItemStyle CssClass="primaryStaticMenuItem" />
            <StaticHoverStyle CssClass="primaryStaticHover" />
            <DynamicMenuStyle CssClass="primaryDynamicMenu" />
            <DynamicMenuItemStyle CssClass="primaryDynamicMenuItem" />
            <DynamicHoverStyle CssClass="primaryDynamicHover" />
        </asp:Menu>
    </div>
    <asp:SiteMapDataSource ID="siteSource1" runat="server" ShowStartingNode="false" />
    <div id="silverlightControlHost">
        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2">
            <param name="source" value="ClientBin/ZInexProblem.xap" />
            <param name="onError" value="onSilverlightError" />
            <param name="background" value="white" />
            <param name="minRuntimeVersion" value="3.0.40818.0" />
            <param name="windowless" value="true" />
            <param name="autoUpgrade" value="true" />
            <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration: none">
                <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight"
                    style="border-style: none" />
            </a>
        </object>
        <iframe id="_sl_historyFrame" style="visibility: hidden; height: 0px; width: 0px;
            border: 0px"></iframe>
    </div>
    </form>
</body>
</html>

Archivo XML web.sitemap para la fuente de los items del menú.

<?xml version="1.0" encoding="utf-8" ?>

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

  <siteMapNode title="Home" description="Home Page" url="Default.aspx">
    <siteMapNode title="News" description="The Latest News" url="News.aspx">
      <siteMapNode title="U.S." description="U.S. News" url="News.aspx?cat=us" />
      <siteMapNode title="World" description="World News" url="News.aspx?cat=world" />
      <siteMapNode title="Technology" description="Technology News" url="News.aspx?cat=tech" />
      <siteMapNode title="Sports" description="Sports News" url="News.aspx?cat=sport" />
    </siteMapNode>
    <siteMapNode title="Weather" description="The Latest Weather" url="Weather.aspx" />
  </siteMapNode>
</siteMap>

El resultado final es:

Codigo Link Código

Fundamentos de Programación Orientada a Objetos desde Silverlight – Level 100


CAPITULO 1

  1. Clases y Objetos 01.
  2. Clases y Objetos 02.
  3. Clases y Objetos 03.
  4. Clases y Objetos 04.

CAPITULO 2

  1. Herencia 05.
  2. Clases abstractas 06.
  3. Interfaces 07.

CAPITULO 3

  1. Modificadores de ámbito 08.
  2. Encapsulamiento 09.
  3. Polimorfismo 10
Entrada destacada

CPOO en Silverlight – Polimorfismo 10


El polimorfismo es nuestro último tema en esta serie de POST para el tutorial de fundamentos de Programación Orientada a Objetos abordada desde Silverlight.

A lo largo de estos post, ya se habrá sugerido de forma abstracta el uso de polimorfismo, pero aquí en este punto es donde se establece su definición y uso.

DEFINAMOS

El polimorfismo, es la capacidad que se tiene en POO para, a partir de una definición base sea posible crear diferentes tipos de comportamiento para un grupo de clases que implementen dicha definición.

Por ejemplo, se tiene la clase Figura y las clases Triangulo, Cuadrado y Circulo y se plantea el requerimiento de calcular el área par a cada figura, en sí el proceso se llama CalcularArea, pero sera la obligación de cada figura generar el código necesario para realizar dicho cálculo.

Veamos el diagrama del clases para el ejemplo:

Como se ve, las clases concretas están implementando la interface IFiguraAreaCalculable, en donde se define un método que apunta a ser de tipo polimorfico, debido a que las clases que implementen esta interface, se someten a generar el código necesario que permita calcular el área correspondiente a cada una de las figuras.

CPOO en Silverlight – Encapsulamiento – 09


En este post se concreta el concepto de Encapsulamiento, pues hasta el momento se habría usado mucho en el recorrido de cada uno de los POST, pero no se había definido un espacio para aclarar este concepro, ¿Por qué asta estas instancias hablar un tema tan importante? Cuando al principio se aborda el tema de encapsulamiento sin haber tenido contacto con términos y conceptos de POO es más tortuoso entender su significado. Luego de estudiar, qué es Clase, Objeto, Propiedades, Comportamientos, Métodos, Estados, Interfaces, Clases Abstractas etc, se puede tener una visión más general sobre el tema.

DEFINAMOS

Encapsulamiento o encapsulación es todo comportamiento, operación o estado interno de un objeto, que para otros objetos o su exterior no es ni relevante ni necesario conocer.

Por ejemplo para aplicaciones silverlight existe el Toolkit de Silverlight que a la hora de crear aplicaciones, permite usar componetes tales como cajas de texto, selectores y otros muchos más controles que permiten crear interfaces de usuario eficientes, compactas e interactivas.

Para ver ejemplos a cerca del uso de estos controles puedes dirigirte al siguiente link.

Ahora es posible afirmar que: El Toolkit de Silverlight encapsula componentes orientados a objetos, los cuales permiten crear y mejorar la experiencia del usuario.

PRACTIQUEMOS

A través de un ejemplo con Silverlight vamos a poner a prueba el poder del encapsulamiento.

1- En una solución de Silverlight en el archivo MainPage.xaml, se va a crear un objeto Ellipse tal cómo se ve en el siguiente código:

<Ellipse x:Name="Balon" Width="50" Height="50" Fill="Black"/>

La idea inicial es poder lograr un efecto de balón con este objeto tipo Shape de Silverlight.

2 – Crearemos 2 botones en la ventana, de forma tal me permitan interactuar con los eventos Click para iniciar y parar la animación.

 <Button Canvas.Left="179" Canvas.Top="265" Content="Empezar"
         Height="23" Name="BtEmpezar" Width="75" Click="BtEmpezar_Click" />
<Button Canvas.Left="270" Canvas.Top="265" Content="Parar"
        Height="23" Name="BtParar" Width="75" Click="BtParar_Click" />

Cada uno de los anteriores objetos con un controlador de evento asociado.

3 – El contenedor principal para este ejemplo sea un Panel tipo canvas, en el cual se va a definir de forma especial un recurso el cual se usaría para lograr el efecto de la animación:

<Canvas x:Name="LayoutRoot" Background="White">
        <Canvas.Resources>
            <Storyboard x:Name="SBAnimacion">
                <DoubleAnimation Storyboard.TargetName="Balon" RepeatBehavior="Forever"
                                 Storyboard.TargetProperty="(Canvas.Top)"
                                 From="0" To="250" Duration="00:00:05">
                    <DoubleAnimation.EasingFunction>
                        <BounceEase Bounces="2" EasingMode="EaseOut" Bounciness="3"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>
            </Storyboard>
        </Canvas.Resources>
</canvas>

Como se ve en el anterior código se ha creado un objeto StoryBoard como recurso del objeto Canvas, este objeto el cual llamaremos SBAnimacion va a contener un objeto de tipo animación que permite definir una interacción o comportamiento del Objeto Balon y Propiedad Top de este, en este caso el tipo de animación será DoubleAnimation, en la cual se configuran los parámetros de dicha animación. Incluido en el código y dentro del objeto DoubleAnimation existe una Propiedad especial, llamada EasingFunction, en el cual se definen unos atributos más, respecto a la animación que se está haciendo, y con el objetivo de obtener el efecto de rebote para el balón(funciones matemáticas de comportamiento para los objetos de la UI en Silverlight).

Cómo se ve hasta este punto no se le ha hecho nada más si no mediante código XAML parametrizar cada objeto respecto a lo que se quiere hacer al momento de ejecutar la animación.

Si vemos el código completo XAML quedará así:

<UserControl x:Class="Silverlight_CPOO_03_Encapsulamiento.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Canvas x:Name="LayoutRoot" Background="White">
        <Canvas.Resources>
            <Storyboard x:Name="SBAnimation">
                <DoubleAnimation Storyboard.TargetName="Balon" RepeatBehavior="Forever"
                                 Storyboard.TargetProperty="(Canvas.Top)"
                                 From="0" To="250" Duration="00:00:05">
                    <DoubleAnimation.EasingFunction>
                        <BounceEase Bounces="2" EasingMode="EaseOut" Bounciness="3"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>
            </Storyboard>
        </Canvas.Resources>
        <Ellipse x:Name="Balon" Width="50" Height="50" Fill="Black"/>
        <Button Canvas.Left="179" Canvas.Top="265" Content="Empezar" Height="23" Name="BtEmpezar" Width="75" Click="BtEmpezar_Click" />
        <Button Canvas.Left="270" Canvas.Top="265" Content="aParar" Height="23" Name="BtParar" Width="75" Click="BtParar_Click" />
    </Canvas>
</UserControl>

Ahora veamos el código de C#:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Silverlight_CPOO_03_Encapsulamiento
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void BtEmpezar_Click(object sender, RoutedEventArgs e)
        {
            SBAnimation.Begin();
        }

        private void BtParar_Click(object sender, RoutedEventArgs e)
        {
            SBAnimation.Stop();
        }
    }
}

Si repasamos el código de C#, en ninguna parte estamos creando algún tipo de funcionalidad para mover el objeto Balón de tipo Ellipse en pantalla, pero si se observa el código de cada evento generado por cada botón, allí se hace el llamado a funciones del objeto StoryBoard siendo estas Begin() y Stop(), cada una para iniciar y parar la animación respectivamente. Hasta este punto solo se ha estado configurando y estableciendo los llamados a los métodos que internamente ejecutan y controlan la animación, lo interesante acá es que para nosotros no es ni relevante, ni necesario conocer cómo se haya implementado el código que este por debajo de esos métodos, y es aquí donde vale destacar el poder de “encapsular”, pues se esta usando un objeto el cual determina cómo utilizar X configuración en pro de ejecutar una animación y después de eso la gestión será interna sin tener nosotros que preocuparnos por mucho más.

Veamos un pequeño video en el que se ve la ejecución de la aplicación:

CPOO en Silverlight – Modificadores de Ámbito– 08


Un tema importante a tener en cuenta en POO son los modificadores de ámbito.

DEFINAMOS

Un modificador de ámbito permite que las partes de un objeto puedan ser expuestas al exterior y a la vez especificar aquellas que no serán accesibles o modificables.

Los tres tipos de modificadores más importantes y a tener muy en cuenta en POO son:

public: Permite que un objeto, clase, propiedad, método entre otros sean accesibles desde cualquier punto de un código de Software Orientado a Objetos.

private: en cuanto a propiedades, métodos u otros componentes que pertenezcan a un objeto sólo se permite accederlos y manipularlos internamente en el bloque que define la clase y en ningún otro lugar más.

protected: Cuando se habla de un objeto que hereda de otro, es posible afirmar que, si un atributo, método u otro está marcado como protected, su uso sera posible en el bloque de la clase que lo define o en aquellas clases que están heredando de la principal.

Complementando este tema, en el siguiente post se habla sobre Encapsulamiento.

CPOO en Silverlight – Herencia – Interfaces – 07


Existe una tercer forma de permitir que una clase sea más robusta, y es a través de la interfaces como puedo indicar a una o varias clases un comportamiento similar.

DEFINAMOS

Una interface permite definir el tipo de objeto más abstracto posible en POO, debido a que no implementa ningún tipo de funcionalidad, carece de constructor y no se puede inicializar ninguna instancia a partir de su propio tipo.

PRACTIQUEMOS

1- Para crear una interface, lo primero es agregar un item tipo clase al proyecto y luego modificarle el atributo class por interface.

2 – Recordemos que a diferencia de las clases abstractas una interfas no implementa nada respecto a sus propiedades o métodos.

3 – A diferencia de herencia las interfaces indican uncicamente la forma de implementación.

Un ejercicio para aplicar esto puede verse en la necesidad de enviar diferentes avisos de publicidad a diferentes tipos de usuario. Por ejemplo en una Pizzería se requiere enviar la oferta del día en una forma muy gráfica a sus clientes favoritos, mientras que una Librería quiere enviar la la oferta del Libro recomendado para el día a sus clientes que son personas elegantes y serias.

Lo primero es crear un componente genérico sobre el cual se puedan cargar los mensajes que van a ser enviados. Y luego tener una forma de crear la interfaz de usuario, el mensaje y enviarlo.

Para este ejercicio se pensó la siguiente interface:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Silverlight_CPOO_02_Herencia_Interfaces
{
    public interface ICreadorMensaje
    {
        string Titulo { get; set; }

        string Contenido { get; set; }

        string De { get; set; }

        string Para { get; set; }

        void CrearMensaje(Panel panel);
    }
}

Como se vé, existen propiedades que permiten especificar el mensaje en sí, y existe un método el cual requiere como parámetro un objeto Panel en el cual se va a escribir o dibujar el mensaje que se envía al usuario final.

Se crean 2 UserControl, para simular los dos tipos de entidades, Librería y Pizzería así:

Páginas: 1 2 3

CPOO en Silverlight – Herencia y Clases Abstractas – 06


En POO además de poder heredar comportamientos o atributos, también es posible permitir que dichos comportamientos o características, sean definidos por las clases que implementen una clase abstracta.

DEFINAMOS

La Clase abstracta es una forma para definir un tipo de Objeto genérico, por lo tanto no será posible crear una instancia a partir de dicha clase.

Por ejemplo, pensemos en clases como Carro, Avión, Cicla o Barco, en común se puede abstraer que todos ellos son vehículos, así la definición de un tipo abstracto será la clase Vehiculo.


    public abstract class Vehiculo
    {
        public abstract void Encender();
        public abstract void Mover();
        public abstract void Parar();
        public abstract void Apagar();
    }

Un Vehiculo no constituye nada puntual para un software orientado a objetos, por lo tanto nunca podría crearse un objeto a partir de esta clase:

Pero si podemos crear clases las cuales hereden esa la clase abstracta:

    public class Avion: Vehiculo
    {

        public override void Encender()
        {

        }

        public override void Mover()
        {

        }

        public override void Parar()
        {

        }

        public override void Apagar()
        {

        }
    }

    public class Carro : Vehiculo
    {

        public override void Encender()
        {

        }

        public override void Mover()
        {

        }

        public override void Parar()
        {

        }

        public override void Apagar()
        {

        }
    }

     public class Barco: Vehiculo
    {

        public override void Encender()
        {

        }

        public override void Mover()
        {

        }

        public override void Parar()
        {

        }

        public override void Apagar()
        {

        }
    }

Así al inicializar un avión, carro o barco, lo que realmente se está haciendo es crear la instancia de un objeto tipo Vehiculo.

Pero esto no se diferencia mucho de lo que se vio en el capítulo anterior de Herencia. Entonces ¿Qué es y para que sirve una clase abstracta?

Para explicar esto veamos el siguiente ejemplo:

Para el ejemplo de la clase Vehiculo existen acciones (métodos) abstractas por ejemplo: Encender, Mover, Parar y Apagar pero para este caso será la responsabilidad de cada Subclase (Carro, Barco, Avion) implementar lo necesario para llevar a cabo esos procesos.

Páginas: 1 2

CPOO en Silverlight – Herencia – 05


Este es uno de los pilares y conceptos más importantes en el paradigma de Programación Orientada a Objetos:

DEFINAMOS

Herencia es una relación entre clases, a través de la cual una clase (Base) permite que sus miembros, atributos, métodos entre otros, puedan ser reutilizados por otras clases (Subclases) y por otra parte se pueda extender la funcionalidad inicial.

Pensemos en un juego de Ajedrez y veamos por ejemplo la necesidad de crear piezas negras y blancas. Pero sinteticemos algo más esto, veamos que hay diferentes tipos de piezas y cada una tiene un tipo de movida diferente.

– Rey – Dama – Alfil – Caballo – Torre – Peón

De este grupo se elige por ejemplo: Caballo y Torre.

El caballo corre en L es decir que segun su posición inicial avanza dos unidades y gira una en sentido lateral.

La torre en cambio se desplaza horizontal y verticalmente tanto como tenga espacio para avanzar.

Según esta pequeña introducción al movimiento de este tipo de piezas. Continuamos y pasamos a abstraer el tipo de objeto base, se tiene en común que ambas tanto Caballo como Torre  son Piezas de jugar al ajedrez. Por lo que se puede ver allí, el primer tipo de objeto es la clase Pieza.

Pero antes de seguir con la definición de la clase, veamos un nuevo tipo de dato  especial, tenemos un enum (Enumeración de tipos de dato), el cual me va a permitir definir si la pieza es blanca o negra, de esta forma se puede conocer si un objeto pertenece al bando blanco o al bando negro.

Posible Diagrama de clases:

Páginas: 1 2 3 4

CPOO en Silverlight – Clases y Objetos – 04


En el siguiente WEBCAST se ve el compendio de los temas tratados hasta el momento, Clases, Objetos en aplicaciones Silverlight.

Código de la clase Balón:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Silverlight_CPOO_01_Clases_Demo
{
    public class Balon
    {
        private const double distancia = 10;
        public Ellipse Grafico { get; set; }

        public Balon()
        {
            Grafico = new Ellipse();
            Grafico.Height = 50;
            Grafico.Width = 50;
            Grafico.Fill = new SolidColorBrush(Colors.Green);
        }

        public void MoverArriba()
        {
            double posTop = (double)Grafico.GetValue(Canvas.TopProperty);
            posTop -= distancia;
            Grafico.SetValue(Canvas.TopProperty, posTop);
        }

        public void MoverAbajo()
        {
            double posTop = (double)Grafico.GetValue(Canvas.TopProperty);
            posTop += distancia;
            Grafico.SetValue(Canvas.TopProperty, posTop);
        }

        public void MoverIzquierda()
        {
            double posLeft = (double)Grafico.GetValue(Canvas.LeftProperty);
            posLeft -= distancia;
            Grafico.SetValue(Canvas.LeftProperty, posLeft);
        }

        public void MoverDerecha()
        {
            double posLeft = (double)Grafico.GetValue(Canvas.LeftProperty);
            posLeft += distancia;
            Grafico.SetValue(Canvas.LeftProperty, posLeft);
        }
    }
}

Código de la clase MainPage

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Silverlight_CPOO_01_Clases_Demo
{
    public partial class MainPage : UserControl
    {
        Balon balon;
        public MainPage()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            balon = new Balon();
            LayoutRoot.Children.Add(balon.Grafico);
        }

        private void btArr_Click(object sender, RoutedEventArgs e)
        {
            balon.MoverArriba();
        }

        private void btIzq_Click(object sender, RoutedEventArgs e)
        {
            balon.MoverIzquierda();
        }

        private void btAba_Click(object sender, RoutedEventArgs e)
        {
            balon.MoverAbajo();
        }

        private void btDer_Click(object sender, RoutedEventArgs e)
        {
            balon.MoverDerecha();
        }
    }
}

Código de la UI para el manejo del Balón:

<UserControl x:Class="Silverlight_CPOO_01_Clases_Demo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Canvas x:Name="LayoutRoot" Background="White">
        <Button Canvas.Left="244" Canvas.Top="227" Content="Arriba" Height="23" Name="btArr" Width="75" Click="btArr_Click" />
        <Button Canvas.Left="163" Canvas.Top="256" Content="Izquierda" Height="23" Name="btIzq" Width="75" Click="btIzq_Click" />
        <Button Canvas.Left="244" Canvas.Top="256" Content="Abajo" Height="23" Name="btAba" Width="75" Click="btAba_Click" />
        <Button Canvas.Left="325" Canvas.Top="256" Content="Derecha" Height="23" Name="btDer" Width="75" Click="btDer_Click" />
    </Canvas>
</UserControl>

Subir ↑