none
ASP.NET WebForms MVVP RRS feed

  • Discussão Geral

  • Estava fazendo uns testes em relação ao assunto acima... e descobri uma forma de viabilizar a metodologia MVVP em WebForms...

    Não fiz muitos testes ainda.. é so uma ideia no momento, mas resolvi compartilhar aqui caso alguem queira dar continuidade.... o fonte completo estou colocando aqui https://skydrive.live.com/redir?resid=B3A201D150ACCEA!986

    Segue um exemplo de como esta funcionando a pagina...

    View: 

    <%@ Page Language="C#" Inherits="Nomad.ASPMVVM.PageView" ViewModel="ASP.MVVM.ViewModel.TesteViewModel" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:TextBox runat="server" Binding='[{ "Property" : "Text", "Path" : "Valor" }]'/>
            <asp:Label runat="server" Binding='[{ "Property" : "Text", "Path" : "Dobro" }]'/>
            <asp:Button Text="Dobrar" runat="server" CommandName="Dobrar" OnCommand="ActionCommand"/>
        </div>
        </form>
    </body>
    </html>
    

    View Model:

    using Nomad.ASPMVVM;
    using System;
    
    namespace ASP.MVVM.ViewModel {
        [Serializable]
        public class TesteViewModel: INotifyPropertyChanged {
            private int _valor;
            private int _dobro;
    
            public int Valor {
                get { return _valor; }
                set {
                    if (Object.Equals(_valor, this) != true) {
                        _valor = value;
                        OnPropertyChanged("Valor");
                    }
                }
            }
    
            public int Dobro {
                get { return _dobro; }
                set {
                    if (Object.Equals(_dobro, this) != true) {
                        _dobro = value;
                        OnPropertyChanged("Dobro");
                    }
                }
            }
    
            public event EventHandler<PropertyChangedEventArgs> PropertyChanged;
    
            protected virtual void OnPropertyChanged(string propertyName) {
                var handler = this.PropertyChanged;
                if (handler != null) {
                    handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
            public void Dobrar() {
                this.Dobro = this.Valor * 2;
            }
        }
    }


    Microsoft Community Contributor

    terça-feira, 4 de setembro de 2012 02:11
    Moderador

Todas as Respostas

  • Estou colocando tambem a classe PageView para dar uma ilustrada melhor com funciona a "engine"

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace Nomad.ASPMVVM {
        [Serializable]
        public class PageView : Page {
            private readonly IDictionary<Control, BindingProperty[]> bindingProperties = new Dictionary<Control, BindingProperty[]>();
    
            private object ViewModelState {
                get { return Context.Items["ViewModelState"]; }
                set {
                    Context.Items.Remove("ViewModelState");
                    Context.Items.Add("ViewModelState", value);                
                }
            }
    
            private string _viewModel;
    
            public string ViewModel {
                get {
                    return _viewModel;
                }
                set {
                    _viewModel = value;
                    InitializeViewModel();
                }
            }
    
            protected override void OnLoad(EventArgs e) {
                InitializeViewModel();
                InitializeBindingProperties(this);
    
                base.OnLoad(e);
            }
    
            private void InitializeViewModel() {
                if (ViewModelState == null && !String.IsNullOrWhiteSpace(this.ViewModel)) {
                    var viewModelAssemblyName = this.ViewModel;
                    var assmebly = Assembly.LoadWithPartialName(viewModelAssemblyName);
                    while (assmebly == null) {
                        if (viewModelAssemblyName.LastIndexOf('.') <= 0) break;
                        viewModelAssemblyName = viewModelAssemblyName.Remove(viewModelAssemblyName.LastIndexOf('.'));
                        assmebly = Assembly.LoadWithPartialName(viewModelAssemblyName);
                    }
    
                    if (assmebly == null) return;
    
                    var vm = assmebly.CreateInstanceOf<INotifyPropertyChanged>(this.ViewModel);
                    if (vm != null) {                    
                        vm.PropertyChanged += ViewModelPropertyChanged;               
                    }
                    this.ViewModelState = vm;
                }
            }
            private void InitializeBindingProperties(Control control) {
                if (control is IAttributeAccessor) {
                    var value = (control as IAttributeAccessor).GetAttribute("Binding");
                    var bindings = BindingProperty.TryParse(value);
                    if (bindings != null) {
                        bindingProperties.Add(control, bindings);
                        ApplyChanges(control);
                    }
                }
    
                control.Controls.OfType<Control>().ToList().ForEach(item => InitializeBindingProperties(item));
            }
    
            private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) {
                this.ApplyBindings(e.PropertyName);
            }
            public void ActionCommand(object sender, CommandEventArgs e) {
                this.ApplyCommand(e.CommandName);
            }
    
            private void ApplyChanges(Control control) {
                if (bindingProperties.Any(item => Object.Equals(item.Key, control)) == false) return;
    
                var bindingsControl = bindingProperties.FirstOrDefault(item => Object.Equals(item.Key, control));
                foreach (var binding in bindingsControl.Value) {
                    var controlProperty = control.GetType().GetProperty(binding.Property);
                    var viewModelProperty = ViewModelState.GetType().GetProperty(binding.Path);
    
                    if (controlProperty != null && viewModelProperty != null) {
                        var value = controlProperty.GetValue(control);
                        var valueType = viewModelProperty.PropertyType; 
                        try {
                            viewModelProperty.SetValue(ViewModelState, Convert.ChangeType(value, valueType));
                        } catch {                        
                            var defaultValue = valueType.Assembly.CreateInstance(valueType.FullName);
                            viewModelProperty.SetValue(ViewModelState, defaultValue);
                        }
                    }
                }        
            }
            private void ApplyBindings(string propertyName) {
                if (bindingProperties.Any(item => item.Value.Any(var => var.Path == propertyName)) != true) return;
    
                var bindingsControl = bindingProperties.FirstOrDefault(item => item.Value.Any(var => var.Path == propertyName));
    
                var control = bindingsControl.Key;
                var binding = bindingsControl.Value.FirstOrDefault(item => item.Path == propertyName);
    
                var controlProperty = control.GetType().GetProperty(binding.Property);
                var viewModelProperty = ViewModelState.GetType().GetProperty(binding.Path);
    
                if (controlProperty != null && viewModelProperty != null) {
                    var value = viewModelProperty.GetValue(ViewModelState);
                    controlProperty.SetValue(control, String.Format(binding.Format, value));
                }
            }
            private void ApplyCommand(string commandName) {
                if (ViewModelState != null) {
                    var method = ViewModelState.GetType().GetMethod(commandName);
                    if (method != null) {
                        method.Invoke(ViewModelState, new object[0]);
                    }
                }
            }
        }
    }
    



    Microsoft Community Contributor

    terça-feira, 4 de setembro de 2012 02:13
    Moderador
  • Rui já tinha visto algo parecido, acho que o legal talvez é criar um framework e hospedar no codeplex ou no github

    Não esqueça de usar o componente </> na barra para posta seu código. Microsoft MCPD,MCTS,MCC

    terça-feira, 4 de setembro de 2012 13:18
    Moderador
  • Rui já tinha visto algo parecido, acho que o legal talvez é criar um framework e hospedar no codeplex ou no github

    Não esqueça de usar o componente </> na barra para posta seu código. Microsoft MCPD,MCTS,MCC

    Entao... essa era ideia... mas to totalmente sem tempo de tocar isso... eu vi o ASP.NET MVVM mas usando o MVC... acho que um nao combina com o outro ja que o legal do MVVM é deixar a View pro designer...

    Vou entrar em ferias semana q vem se consegui um tempo monto algo no CodePlex


    Microsoft Community Contributor

    quinta-feira, 6 de setembro de 2012 00:06
    Moderador
  • Ok... estou subindo uma versão no CodePlex... quem tiver interesse favor entrar em contato...

    Aproveitei e dei uma melhorada... fiz alguns testes e me pareceu bem promissor isso:

    https://webformmvvm.codeplex.com/

    um exemplo de como ficou a View:

    <%@ Page Language="C#" Inherits="Nomad.ASPMVVM.PageView" ViewModel="ASP.MVVM.ViewModel.TesteViewModel" %>
    
    <%@ Import Namespace="Nomad.ASPMVVM" %>
    
    <!DOCTYPE html>
    
    <script runat="server">
        private BindingProperty ValorProperty = new BindingProperty { Property = "Text", Path = "Valor" };
        private BindingProperty ResultadoProperty = new BindingProperty { Property = "Text", Path = "Resultado", Format = "{0:#,##0.00}" };
        private BindingProperty OperacoesProperty = new BindingProperty { Property = "DataSource", Path = "Operacoes", NeedsBind = true };
        private BindingProperty OperacaoSelecionadaProperty = new BindingProperty { Property = "SelectedValue", Path = "OperacaoSelecionada" };
    
        private BindingProperty CalcularCommand = new BindingProperty { Path = "Calcular", IsCommand = true };
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:ScriptManager runat="server" />
            <asp:UpdatePanel runat="server">
                <ContentTemplate>
                    <p>
                        <asp:TextBox runat="server" Binding='<%# Eval(ValorProperty) %>' />                   
                        <asp:DropDownList runat="server" Binding='<%# Eval(OperacoesProperty, OperacaoSelecionadaProperty) %>' />
                        <asp:Button Text="Calcular" runat="server" Binding='<%# Eval(CalcularCommand) %>'  />
                    </p>
                    <p>
                        <asp:Label runat="server" Binding='<%# Eval(ResultadoProperty) %>' />
                    </p>
                </ContentTemplate>
            </asp:UpdatePanel>
        </form>
    </body>
    </html>
    


    Microsoft Community Contributor

    quinta-feira, 6 de setembro de 2012 22:33
    Moderador