locked
Static Property Mvvm BindableBase object reference error

    Question

  • I have a ViewModel that derives from BindableBase that contains a property for visibility of a grid in the XAML.

            /// <summary>
            /// Visibility for the download buttons and status messages area
            /// </summary>
            private Visibility _DownLoadVisibility = Visibility.Collapsed;
            public Visibility DownLoadVisibility
            {
                get { return _DownLoadVisibility; }
                set
                {
                    SetProperty(ref _DownLoadVisibility, value);
                }
            }

    From a method marked static in that ViewModel I can not update the DownLoadVisibility

    Error: Error 1 An object reference is required for the non-static field, method, or property

    If I mark the DownLoadVisibility static then I get the object reference error on the set of DownLoadVisibility

            private static Visibility _DownLoadVisibility = Visibility.Collapsed;
            public static Visibility DownLoadVisibility
            {
                get { return _DownLoadVisibility; }
                set
                {
                    SetProperty(ref _DownLoadVisibility, value); // <- error
                  }
            }
    
    If I do something like this vm is not bound to the Xaml.

                AppHubViewModel vm = new AppHubViewModel();
                vm.DownLoadVisibility = Visibility.Visible;
                // DownLoadVisibility = Visibility.Visible;

    Guidance?

    Background: I'm calling a static method in the ViewModel from the XAML code behind as the GridView doesn't have Command. I had the application working when the code was in XAML code behind. I've moved it into the ViewModel and have all of the functionality working mainly by making static in the ViewModel. One other problem I will have is how to update an item in the ViewModel ObservableCollection. I think that once I understand and solve the DownLoadVisibility problem that solution will follow.

            private async void RemoteSoundsView_ItemClick(object sender, ItemClickEventArgs e)
            {
                var sfx = e.ClickedItem as ExtendedSfx;
                // sfx.isLocal = true;     // test play logic. It works! 
                // How do I get the isLocal in an item in the Observable collection updated? 
                if (sfx.isLocal) // if true then play the sound rather than dislaying the menu. 
                {
                    AppHubViewModel.LocalSoundsView_ItemClick(sender, e); 
                }
                else
                {
                    var md = new MessageDialog(sfx.SfxDescription, sfx.SfxName);
                    md.Commands.Add(new UICommand(
                        "Download Sfx", async (o) => { await AppHubViewModel.DoDownLoad(sender, e); }));
                    md.Commands.Add(new UICommand("Preview Sfx", (o) => { }));
                    md.Commands.Add(new UICommand("Close", (o) => { }));
                    await md.ShowAsync();
                }
            }


    Life is terminal.

    Tuesday, September 18, 2012 8:42 PM

Answers

All replies

  • dont use SetProperty method and implement the setter your self?
    Tuesday, September 18, 2012 8:45 PM
  • There appear to be a few things at play here...

    1) If you are starting with the GridView and want to get to the page's ViewModel object, you may be able to find it within the GridView's DataContext (not 100% sure - need to see more code and context around where the interaction is initiating to be sure.)  Ultimately, I REALLY don't think using static is really what you want to do.

    2) It is more common to see the ViewModel property be a Boolean and a ValueConverter used to convert (project?) the Boolean property in the binding to a Visibility.  This is so common, in fact, that a BooleanToVisibilityConverter is provided for new projects (look in the Common folder)

    3) The 3rd code sample above where you create a new view model instance and then set its property, but don't see a change in the UI - if I understand what you're asking correctly, it is because your page is data-bound to an instance of the view model class (again, I need more code to tell you where that instance may have originated, but I would hazard a guess at OnNavigatedTo and LoadState.)   In that code above, you're creating a new, distinct instance, and setting the property.  The UI/XAML doesn't know that this new instance exists - it isn't in your page's DataContext (and you probably don't want it to be - you likely already have a perfectly good ViewModel hanging out there.)

    4) Didn't really grasp what you were asking for in the fourth code block.  Sorry.

    John

    Tuesday, September 18, 2012 11:15 PM
  • I've taken a different approach. I asked this question

    http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/570f3e6f-4eb8-4422-8f72-0e6db6bd4866/

    I received an answer, implemented and the problem is solved. Much better binding into ViewModel with Command on a button. 



    Life is terminal.

    • Marked as answer by jhalbrecht Sunday, September 23, 2012 8:55 PM
    Sunday, September 23, 2012 8:55 PM