none
ViewModelLocator declarado en el XAML + Binding de un Application Bar a un Command = NullReferenceException RRS feed

  • Pregunta

  • Estoy desarrollando una aplicación para WP7 usando MVVM Light Toolkit, la cual inicialmente funciona sin problemas.

    Para cada Vista, establezco su  DataContext en el codebehind de la vista como muestro a continuación:

     

    public partial class MainPage : PhoneApplicationPage 
    { 
        // Constructor 
        public MainPage() 
        { 
            InitializeComponent(); 
            DataContext = ViewModelLocator.MainPageViewModelStatic;                           
        } 
    } 
    
    

     

    Mi ViewModelLocator está declarado en el archivo App.xaml 

     

    <Application.Resources>         
        <vm:ViewModelLocator x:Key="Locator"  
                            d:IsDataSource="True" /> 
    </Application.Resources> 
    
    

    Sin embargo cuando intento establecer el datacontext desde el codigo XAML en lugar de desde el codebehind obtengo un error.

    Este es el codebehind modificado:

    public partial class MainPage : PhoneApplicationPage 
    { 
        // Constructor 
        public MainPage() 
        { 
            InitializeComponent(); 
            //DataContext = ViewModelLocator.MainPageViewModelStatic;                           
        } 
    } 
    
    
    Y el archivo  XAML:
    <phone:PhoneApplicationPage  
    x:Class="Views.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    xmlns:au="clr-namespace:AppBarUtils;assembly=AppBarUtils" 
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="696" 
    FontFamily="{StaticResource PhoneFontFamilyNormal}" 
    FontSize="{StaticResource PhoneFontSizeNormal}" 
    Foreground="{StaticResource PhoneForegroundBrush}" 
    SupportedOrientations="Portrait" Orientation="Portrait" 
    shell:SystemTray.IsVisible="True"    
    DataContext="{Binding MainPageViewModel, Source={StaticResource Locator}}"> 
     
    <!--LayoutRoot is the root grid where all page content is placed--> 
    <Grid x:Name="LayoutRoot" Background="Transparent"> 
    </Grid> 
     
    <!--Sample code showing usage of ApplicationBar--> 
     
    <phone:PhoneApplicationPage.ApplicationBar> 
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" BackgroundColor="{StaticResource PhoneAccentColor}"> 
            <shell:ApplicationBarIconButton IconUri="/Resources/Icons/appbar.check.rest.png" Text="Iniciar" />             
            <shell:ApplicationBar.MenuItems> 
                <shell:ApplicationBarMenuItem Text="Iniciar" />                 
            </shell:ApplicationBar.MenuItems> 
        </shell:ApplicationBar> 
    </phone:PhoneApplicationPage.ApplicationBar> 
     
    <i:Interaction.Behaviors> 
        <au:AppBarItemCommand 
        ItemText="Iniciar" Command="{Binding IniciarSesion}" /> 
    </i:Interaction.Behaviors> 
     
    </phone:PhoneApplicationPage>
    
    Y este es mi ViewModel:
    namespace ViewModels 
    { 
      public class MainPageViewModel : ViewModelBase 
      { 
        public const string mensajePropertyName = "mensaje"; 
     
        private string _mensaje = ""; 
     
        public string mensaje 
        { 
            get 
            { 
                return _mensaje; 
            } 
     
            set 
            { 
                if (_mensaje == value) 
                { 
                    return; 
                } 
     
                var oldValue = _mensaje; 
                _mensaje = value; 
     
                RaisePropertyChanged(mensajePropertyName); 
            } 
        }        
     
        private RelayCommand _iniciarSesion; 
     
        public RelayCommand IniciarSesion 
        { 
            get 
            { 
                if (_iniciarSesion == null) 
                { 
                    _iniciarSesion=new RelayCommand((()=> this.mensaje="hola")); 
                } 
                return _iniciarSesion; 
            } 
     
        } 
     
      } 
    } 
    

    Una pista acerca de lo que puede estar pasando es que si elimino el binding asociado al AppBarItemCommand y en su lugar añado otro control con un binding a la propiedad mensaje del viewmodel la aplicación se ejecuta sin problemas. El problema se da justamente cuando establezco el binding del AppBarItemCommand en el XAML.

    Por si es de ayuda, esta es la stack trace que devuelve la excepcion:

    at AppBarUtils.AppBarItemCommand.ChangeIsEnabled() 
    at AppBarUtils.AppBarItemCommand.OnCommandChanged(DependencyPropertyChangedEventArgs e) 
    at AppBarUtils.AppBarItemCommand.CommandPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object oldValue, Object newValue) 
    at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation) 
    at System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp) 
    at System.Windows.Data.BindingExpression.RefreshExpression() 
    at System.Windows.Data.BindingExpression.SendDataToTarget() 
    at System.Windows.Data.BindingExpression.SourceAcquired() 
    at System.Windows.Data.BindingExpression.InheritanceContextChanged(Object sender, EventArgs e) 
    at System.Windows.DependencyObject.OnInheritanceContextChanged(Object sender, EventArgs e) 
    at System.Windows.DOCollection.AddInternal(DependencyObject value) 
    at System.Windows.PresentationFrameworkCollection`1.Add(DependencyObject value) 
    at System.Windows.DependencyObjectCollection`1.System.Collections.IList.Add(Object value) 
    at MS.Internal.XamlManagedRuntimeRPInvokes.Add(XamlQualifiedObject& qoCollection, XamlPropertyToken inCollectionProperty, XamlQualifiedObject& inValue) 
    at MS.Internal.XcpImports.Application_LoadComponentNative(IntPtr pContext, IntPtr pComponent, UInt32 cUriStringLength, String uriString, UInt32 cXamlStrLength, Byte* pXamlStr, UInt32 cAssemblyStrLength, String assemblyStr) 
    at MS.Internal.XcpImports.Application_LoadComponent(IManagedPeerBase componentAsDO, String resourceLocator, UnmanagedMemoryStream stream, UInt32 numBytesToRead, String assemblyString) 
    at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator) 
    at PCCOM.Distrib.Presentation.PreventaClient.Views.MainPage.InitializeComponent() 
    at PCCOM.Distrib.Presentation.PreventaClient.Views.MainPage..ctor() 
    at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstructorInfo rtci, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark) 
    at System.Reflection.RuntimeConstructorInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark) 
    at System.Activator.InternalCreateInstance(Type type, Boolean nonPublic, StackCrawlMark& stackMark) 
    at System.Activator.CreateInstance(Type type) 
    at System.Windows.Navigation.PageResourceContentLoader.BeginLoad_OnUIThread(AsyncCallback userCallback, PageResourceContentLoaderAsyncResult result) 
    at System.Windows.Navigation.PageResourceContentLoader.<>c__DisplayClass4.<BeginLoad>b__0(Object args) 
    at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark) 
    at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark) 
    at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) 
    at System.Delegate.DynamicInvokeOne(Object[] args) 
    at System.MulticastDelegate.DynamicInvokeImpl(Object[] args) 
    at System.Delegate.DynamicInvoke(Object[] args) 
    at System.Windows.Threading.DispatcherOperation.Invoke() 
    at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority) 
    at System.Windows.Threading.Dispatcher.OnInvoke(Object context) 
    at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args) 
    at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args) 
    at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult) 

    ¿Alguna idea?

    Gracias


     

    martes, 25 de octubre de 2011 16:30