none
Patrón de Diseño MVVM RRS feed

  • Pregunta

  • Hola 

    Estoy usando en ejemplo de Josue Yeray,  es un video donde muestra como usar el patrón de diseño MVVM en Silverlight, estoy usando VS 2012 y WPF, el error me parece que es en el XAML, muestro el código.

    View

    <Window x:Class="SampleMVVM.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="28*"/>
                <ColumnDefinition Width="19*"/>
            </Grid.ColumnDefinitions>
            <Label Content="Original URL :" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="25,0,0,283" RenderTransformOrigin="1.695,3.567"/>
            <Label Content="Shortened URL :" HorizontalAlignment="Left" VerticalAlignment="Top" RenderTransformOrigin="1.903,4.933" Margin="25,134,0,0"/>
            <TextBox Name="txtOriginalURL" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=OriginalURL, Mode=TwoWay}" VerticalAlignment="Top" Width="325" Margin="39,58,0,0" Grid.ColumnSpan="2"/>
            <TextBox Name="txtShortenedURL" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=ShortenedURL, Mode=TwoWay}" VerticalAlignment="Top" Width="325" Margin="39,204,0,0" Grid.ColumnSpan="2"/>
            <Button Name="btnEjecutar" Content="Short IT!" HorizontalAlignment="Left" VerticalAlignment="Top" Width="325" Margin="39,97,0,0"
                    Command="{Binding ShortURLCommand}" Grid.ColumnSpan="2" />
    
        </Grid>
    </Window>


    Model

    using System.Text;
    using System.Threading.Tasks;
    using System.ComponentModel;
    
    namespace SampleMVVM.Model
    {
        public class URLShortModel : INotifyPropertyChanged
        {
            public URLShortModel()
            {
                
            }
    
            private string _shortedURL;
            public string shortedURL
            {
                get { return _shortedURL; }
                set
                {
                    _shortedURL = value;
                    OnPropertyChanged("shortedURL");
                }
            }
    
            public string originalURL { get; set; }
    
            public void ShortURL()
            {
                string url = Uri.EscapeUriString(originalURL);
                _shortedURL = string.Empty;
                url = string.Format(@"http://is.gd/api.php?longurl={0}", url);
                WebClient peticionUrl = new WebClient();
                peticionUrl.DownloadStringCompleted += DownloadComplete;
                peticionUrl.DownloadStringAsync(new Uri(url));
    
            }
    
            private void DownloadComplete(object sender, DownloadStringCompletedEventArgs e)
            {
                if(e.Error != null)
                {
                    throw e.Error;
                }
                if(e.Result != null)
                {
                    shortedURL = e.Result;
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }


    ViewModel

    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Input;
    
    namespace SampleMVVM.ViewModel
    {
        public class CommandBase : ICommand
        {
            private Action handler;
            private bool _IsEnabled;
    
            public CommandBase(Action _handler)
            {
                handler = _handler;
            }
    
            public bool IsEnabled
            {
                get { return _IsEnabled; }
                set
                {
                    if(value != _IsEnabled)
                    {
                        _IsEnabled = value;
                        if(CanExecuteChanged != null)
                        {
                            CanExecuteChanged(this, EventArgs.Empty);
                        }
                    }
                }
            }
    
            // Llamada desde WPF, le indica si el comanado se puede ejecutar, no la llamamos directamente nosotros.
            public bool CanExecute(object parameter)
            {
                return IsEnabled;
            }
    
            // Ejecuta la accion indicada en la variable handler.
            public void Execute(object parameter)
            {
                handler();
            }
    
            public event EventHandler CanExecuteChanged;
        }
    }
    
    =============================================
    
    using System.Windows.Input;
    using System.Windows.Shapes;
    using System.ComponentModel;
    
    namespace SampleMVVM.ViewModel
    {
        public class URLShortViewModel : INotifyPropertyChanged 
        {
            public URLShortViewModel()
            {
                _ShortURLCommand = new CommandBase(ShortURLMethod) {IsEnabled = false};
                Modelo = new Model.URLShortModel();
                Modelo.PropertyChanged += new PropertyChangedEventHandler(Modelo_PropertyChanged);
            }
    
            private SampleMVVM.Model.URLShortModel Modelo;
    
            private string _originalurl = string.Empty;
            private string _shortenedurl = string.Empty;
    
            public string OriginalURL
            {
                get { return _originalurl; }
                set { 
                    _originalurl = value;
                    OnPropertyChanged("OriginalURL");
    
                    if(string.IsNullOrEmpty(_originalurl))
                    {
                        (ShortURLCommand as CommandBase).IsEnabled = false;
                    }
                    else
                    {
                        (ShortURLCommand as CommandBase).IsEnabled = true;
                    }
    
                    }
            }
    
            public string ShortenedURL
            {
                get { return _shortenedurl; }
                set { _shortenedurl = value;
                OnPropertyChanged("ShortenedURL");}
            }
    
            private readonly ICommand _ShortURLCommand;
            public ICommand ShortURLCommand
            { get { return _ShortURLCommand; } }
    
            public void ShortURLMethod()
            {
                Modelo.originalURL = OriginalURL;
                Modelo.ShortURL();
            }
    
    
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
            }
    
            void Modelo_PropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                ShortenedURL = Modelo.shortedURL;
            }
        }
    }


    Este es un ejemplo de acortar el tamaño de una url, espero me puedan ayudar ya que estoy aplicando para WPF, según la indicación de Yeray este ejemplo se puede aplicar para WPF, WP, Silverligth.

    Este es el error que me sale.



    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    • Editado Pedro Ávila domingo, 4 de agosto de 2013 4:16 xxxxx
    domingo, 4 de agosto de 2013 4:09

Respuestas

  • Ya solucione el problema de que no lanzaba la app, era pq? puse el MainWindow.xaml dentro de una carpeta pero lo solucione de esta manera actualizando el StartupUri.

    <Application x:Class="SampleMVVM.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 StartupUri="View\MainWindow.xaml">
        <Application.Resources>
             
        </Application.Resources>
    </Application>
    El problema es que cuando hago click al botón no funciona me parece que esta desabilitado, pq? he puesto un break point y no pasa nada no hay comunicación.


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú



    • Editado Pedro Ávila domingo, 4 de agosto de 2013 12:28 xxxxxxxxx
    • Marcado como respuesta Pedro Ávila domingo, 4 de agosto de 2013 13:02
    domingo, 4 de agosto de 2013 12:22
  • Ya lo solucione!!!

    <Window x:Class="SampleMVVM.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"
            xmlns:viewmodel="clr-namespace:SampleMVVM.ViewModel" >
            <Window.DataContext>
        <viewmodel:URLShortViewModel></viewmodel:URLShortViewModel>
            </Window.DataContext>

    Tuve que asignarle el DataContex al principio me confuncdí ya que el original era sobre un UserControl en SilverLigth pero veo que es casi lo mismo. 


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    • Marcado como respuesta Pedro Ávila domingo, 4 de agosto de 2013 13:02
    domingo, 4 de agosto de 2013 13:00

Todas las respuestas

  •  Espero se pueda apreciar mejor el error en esta imagen


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    domingo, 4 de agosto de 2013 4:16
  • hola

    validaste si la definicion de

    <Window x:Class="SampleMVVM.MainWindow"

    lo que marco en negrita es correcta

    el codigo asociado al xaml esta en ese namespace

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    domingo, 4 de agosto de 2013 4:48
  • El namespace es SampleMVVM

    Acá importo el namespace del ViewModel

    <Window x:Class="SampleMVVM.MainWindows"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"
            xmlns:viewmodel="clr-namespace:SampleMVVM.ViewModel">

    Pero, no veo que lo use en el xaml

    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú


    • Editado Pedro Ávila domingo, 4 de agosto de 2013 11:38 xxxxxxxxxxx
    domingo, 4 de agosto de 2013 11:21
  • Como puedo establecer el DataContex de la venta, para poder tener acceso a las propiedades publicas y comandos, pero esto como lo hago en el xaml.

    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    domingo, 4 de agosto de 2013 11:43
  • El cambio que hago también es esto, el MainWindow.xaml


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    domingo, 4 de agosto de 2013 12:06
  • Ya solucione el problema de que no lanzaba la app, era pq? puse el MainWindow.xaml dentro de una carpeta pero lo solucione de esta manera actualizando el StartupUri.

    <Application x:Class="SampleMVVM.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 StartupUri="View\MainWindow.xaml">
        <Application.Resources>
             
        </Application.Resources>
    </Application>
    El problema es que cuando hago click al botón no funciona me parece que esta desabilitado, pq? he puesto un break point y no pasa nada no hay comunicación.


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú



    • Editado Pedro Ávila domingo, 4 de agosto de 2013 12:28 xxxxxxxxx
    • Marcado como respuesta Pedro Ávila domingo, 4 de agosto de 2013 13:02
    domingo, 4 de agosto de 2013 12:22
  • Ya lo solucione!!!

    <Window x:Class="SampleMVVM.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"
            xmlns:viewmodel="clr-namespace:SampleMVVM.ViewModel" >
            <Window.DataContext>
        <viewmodel:URLShortViewModel></viewmodel:URLShortViewModel>
            </Window.DataContext>

    Tuve que asignarle el DataContex al principio me confuncdí ya que el original era sobre un UserControl en SilverLigth pero veo que es casi lo mismo. 


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    • Marcado como respuesta Pedro Ávila domingo, 4 de agosto de 2013 13:02
    domingo, 4 de agosto de 2013 13:00
  • que tal Pedro, mira llevo algun tiempo tratando el patron MVVM y se complica al tener varios Models, ViewModels, Commands, Views, etc..

    una sujerencia utiliza IDataErrorInfo en el Model asi te libras de tenere que hacerlo en el ViewModel y controlas mejor el ICommand mira este video lo explican a la perfeccion http://www.youtube.com/watch?v=OOHDie8BdGI&list=PLCm5JR7pee-oNgcJA9PeI82a2y88CbRXY&index=3

    saludos,

    martes, 6 de agosto de 2013 13:39