locked
The type or namespace name 'BindableBase' does not exist in the namespace RRS feed

  • Question

  • I'm going through the Contoso Cookbook training app and i'm getting the following error. 

    Error 1 The type or namespace name 'BindableBase' does not exist in the namespace 'ContosoCookbook.Common' (are you missing an assembly reference?) C:\Users\Kevin\documents\visual studio 2013\Projects\ContosoCookbook\ContosoCookbook\DataModel\RecipeDataSource.cs 50 69 ContosoCookbook

    This app was designed for Windows 8 and I started with a Windows 8.1 template.  I'm guessing that BindableBase is no longer supported, However, I'm not sure how to resolve this.  I'm trying to learn Windows Store App development and any help would be appreciated.

    Kevin

    // ----------------------------------------------------------------------------------
    // Microsoft Developer & Platform Evangelism
    // 
    // Copyright (c) Microsoft Corporation. All rights reserved.
    // 
    // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
    // EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
    // OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
    // ----------------------------------------------------------------------------------
    // The example companies, organizations, products, domain names,
    // e-mail addresses, logos, people, places, and events depicted
    // herein are fictitious.  No association with any real company,
    // organization, product, domain name, email address, logo, person,
    // places, or events is intended or should be inferred.
    // ----------------------------------------------------------------------------------
    
    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using Windows.ApplicationModel.Resources.Core;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Media.Imaging;
    using System.Net.Http;
    using Windows.Data.Json;
    using Windows.ApplicationModel;
    using Windows.Storage.Streams;
    using System.Threading.Tasks;
    using Windows.Storage;
    using ContosoCookbook.Data;
    using ContosoCookbook.Common;
    
    // The data model defined by this file serves as a representative example of a strongly-typed
    // model that supports notification when members are added, removed, or modified.  The property
    // names chosen coincide with data bindings in the standard item templates.
    //
    // Applications may use this model as a starting point and build on it, or discard it entirely and
    // replace it with something appropriate to their needs.
    
    namespace ContosoCookbook.Data
    {
        /// <summary>
        /// Base class for <see cref="RecipeDataItem"/> and <see cref="RecipeDataGroup"/> that
        /// defines properties common to both.
        /// </summary>
        [Windows.Foundation.Metadata.WebHostHidden]
        public abstract class RecipeDataCommon : ContosoCookbook.Common.BindableBase   
        {
            internal  static Uri _baseUri = new Uri("ms-appx:///");
    
            public RecipeDataCommon(String uniqueId, String title, String shortTitle, String imagePath)
            {
                this._uniqueId = uniqueId;
                this._title = title;
                this._shortTitle = shortTitle;
                this._imagePath = imagePath;
            }
    
            private string _uniqueId = string.Empty;
            public string UniqueId
            {
                get { return this._uniqueId; }
                set { this.SetProperty(ref this._uniqueId, value); }
            }
    
            private string _title = string.Empty;
            public string Title
            {
                get { return this._title; }
                set { this.SetProperty(ref this._title, value); }
            }
    
            private string _shortTitle = string.Empty;
            public string ShortTitle
            {
                get { return this._shortTitle; }
                set { this.SetProperty(ref this._shortTitle, value); }
            }
    
            private ImageSource _image = null;
            private String _imagePath = null;
    
            public Uri ImagePath
            {
                get
                {
                    return new Uri(RecipeDataCommon._baseUri, this._imagePath); 
                }
            } 
    
            public ImageSource Image
            {
                get
                {
                    if (this._image == null && this._imagePath != null)
                    {
                        this._image = new BitmapImage(new Uri(RecipeDataCommon._baseUri, this._imagePath));
                    }
                    return this._image;
                }
    
                set
                {
                    this._imagePath = null;
                    this.SetProperty(ref this._image, value);
                }
            }
    
            public void SetImage(String path)
            {
                this._image = null;
                this._imagePath = path;
                this.OnPropertyChanged("Image");
            }
    
            public string GetImageUri()
            {
                return _imagePath;
            }
        }
    
        /// <summary>
        /// Recipe item data model.
        /// </summary>
        public class RecipeDataItem : RecipeDataCommon
        {
            public RecipeDataItem()
                : base(String.Empty, String.Empty, String.Empty, String.Empty)
            {
            }
            
            public RecipeDataItem(String uniqueId, String title, String shortTitle, String imagePath, int preptime, String directions, ObservableCollection<string> ingredients, RecipeDataGroup group)
                : base(uniqueId, title, shortTitle, imagePath)
            {
                this._preptime = preptime;
                this._directions = directions;
                this._ingredients = ingredients;
                this._group = group;
            }
    
            private int _preptime = 0;
            public int PrepTime
            {
                get { return this._preptime; }
                set { this.SetProperty(ref this._preptime, value); }
            }
            
            private string _directions = string.Empty;
            public string Directions
            {
                get { return this._directions; }
                set { this.SetProperty(ref this._directions, value); }
            }
    
            private ObservableCollection<string> _ingredients;
            public ObservableCollection<string> Ingredients
            {
                get { return this._ingredients; }
                set { this.SetProperty(ref this._ingredients, value); }
            }
        
            private RecipeDataGroup _group;
            public RecipeDataGroup Group
            {
                get { return this._group; }
                set { this.SetProperty(ref this._group, value); }
            }
    
            private ImageSource _tileImage;
            private string _tileImagePath;
    
            public Uri TileImagePath
            {
                get
                {
                    return new Uri(RecipeDataCommon._baseUri, this._tileImagePath);
                }
            }
            
            public ImageSource TileImage
            {
                get
                {
                    if (this._tileImage == null && this._tileImagePath != null)
                    {
                        this._tileImage = new BitmapImage(new Uri(RecipeDataCommon._baseUri, this._tileImagePath));
                    }
                    return this._tileImage;
                }
                set
                {
                    this._tileImagePath = null;
                    this.SetProperty(ref this._tileImage, value);
                }
            }
    
            public void SetTileImage(String path)
            {
                this._tileImage = null;
                this._tileImagePath = path;
                this.OnPropertyChanged("TileImage");
            }
        }
    
        /// <summary>
        /// Recipe group data model.
        /// </summary>
        public class RecipeDataGroup : RecipeDataCommon
        {
            public RecipeDataGroup()
                : base(String.Empty, String.Empty, String.Empty, String.Empty)
            {
            }
            
            public RecipeDataGroup(String uniqueId, String title, String shortTitle, String imagePath, String description)
                : base(uniqueId, title, shortTitle, imagePath)
            {
            }
    
            private ObservableCollection<RecipeDataItem> _items = new ObservableCollection<RecipeDataItem>();
            public ObservableCollection<RecipeDataItem> Items
            {
                get { return this._items; }
            }
    
            public IEnumerable<RecipeDataItem> TopItems
            {
                // Provides a subset of the full items collection to bind to from a GroupedItemsPage
                // for two reasons: GridView will not virtualize large items collections, and it
                // improves the user experience when browsing through groups with large numbers of
                // items.
                //
                // A maximum of 12 items are displayed because it results in filled grid columns
                // whether there are 1, 2, 3, 4, or 6 rows displayed
                get { return this._items.Take(12); }
            }
    
            private string _description = string.Empty;
            public string Description
            {
                get { return this._description; }
                set { this.SetProperty(ref this._description, value); }
            }
    
            private ImageSource _groupImage;
            private string _groupImagePath;  
    
            public ImageSource GroupImage
            {
                get
                {
                    if (this._groupImage == null && this._groupImagePath != null)
                    {
                        this._groupImage = new BitmapImage(new Uri(RecipeDataCommon._baseUri, this._groupImagePath));
                    }
                    return this._groupImage;
                }
                set
                {
                    this._groupImagePath = null;
                    this.SetProperty(ref this._groupImage, value);
                }
            }
    
            public int RecipesCount
            {
                get
                {
                    return this.Items.Count; 
                } 
            } 
    
            public void SetGroupImage(String path)
            {
                this._groupImage = null;
                this._groupImagePath = path;
                this.OnPropertyChanged("GroupImage");
            }
        }
    
        /// <summary>
        /// Creates a collection of groups and items.
        /// </summary>
        public sealed class RecipeDataSource
        {
            //public event EventHandler RecipesLoaded;
    
            private static RecipeDataSource _recipeDataSource = new RecipeDataSource();
            
            private ObservableCollection<RecipeDataGroup> _allGroups = new ObservableCollection<RecipeDataGroup>();
            public ObservableCollection<RecipeDataGroup> AllGroups
            {
                get { return this._allGroups; }
            }
    
            public static IEnumerable<RecipeDataGroup> GetGroups(string uniqueId)
            {
                if (!uniqueId.Equals("AllGroups")) throw new ArgumentException("Only 'AllGroups' is supported as a collection of groups");
    
                return _recipeDataSource.AllGroups;
            }
    
            public static RecipeDataGroup GetGroup(string uniqueId)
            {
                // Simple linear search is acceptable for small data sets
                var matches = _recipeDataSource.AllGroups.Where((group) => group.UniqueId.Equals(uniqueId));
                if (matches.Count() == 1) return matches.First();
                return null;
            }
    
            public static RecipeDataItem GetItem(string uniqueId)
            {
                // Simple linear search is acceptable for small data sets
                var matches = _recipeDataSource.AllGroups.SelectMany(group => group.Items).Where((item) => item.UniqueId.Equals(uniqueId));
                if (matches.Count() == 1) return matches.First();
                return null;
            }
    
            public static async Task LoadRemoteDataAsync()
            {
                // Retrieve recipe data from Azure
                var client = new HttpClient();
                client.MaxResponseContentBufferSize = 1024 * 1024; // Read up to 1 MB of data
                var response = await client.GetAsync(new Uri("http://contosorecipes8.blob.core.windows.net/AzureRecipesRP"));
                var result = await response.Content.ReadAsStringAsync();
    
                // Parse the JSON recipe data
                var recipes = JsonArray.Parse(result);
    
                // Convert the JSON objects into RecipeDataItems and RecipeDataGroups
                CreateRecipesAndRecipeGroups(recipes);
            }
    
            public static async Task LoadLocalDataAsync()
            {
                // Retrieve recipe data from Recipes.txt
                var file = await Package.Current.InstalledLocation.GetFileAsync("Data\\Recipes.txt");
                var result = await FileIO.ReadTextAsync(file);
    
                // Parse the JSON recipe data
                var recipes = JsonArray.Parse(result);
    
                // Convert the JSON objects into RecipeDataItems and RecipeDataGroups
                CreateRecipesAndRecipeGroups(recipes);
            }
    
            private static void CreateRecipesAndRecipeGroups(JsonArray array)
            {
                foreach (var item in array)
                {
                    var obj = item.GetObject();
                    RecipeDataItem recipe = new RecipeDataItem();
                    RecipeDataGroup group = null;
    
                    foreach (var key in obj.Keys)
                    {
                        IJsonValue val;
                        if (!obj.TryGetValue(key, out val))
                            continue;
    
                        switch (key)
                        {
                            case "key":
                                recipe.UniqueId = val.GetNumber().ToString();
                                break;
                            case "title":
                                recipe.Title = val.GetString();
                                break;
                            case "shortTitle":
                                recipe.ShortTitle = val.GetString();
                                break;
                            case "preptime":
                                recipe.PrepTime = (int)val.GetNumber();
                                break;
                            case "directions":
                                recipe.Directions = val.GetString();
                                break;
                            case "ingredients":
                                var ingredients = val.GetArray();
                                var list = (from i in ingredients select i.GetString()).ToList();
                                recipe.Ingredients = new ObservableCollection<string>(list);
                                break;
                            case "backgroundImage":
                                recipe.SetImage(val.GetString());
                                break;
                            case "tileImage":
                                recipe.SetTileImage(val.GetString());
                                break;
                            case "group":
                                var recipeGroup = val.GetObject();
    
                                IJsonValue groupKey;
                                if (!recipeGroup.TryGetValue("key", out groupKey))
                                    continue;
    
                                group = _recipeDataSource.AllGroups.FirstOrDefault(c => c.UniqueId.Equals(groupKey.GetString()));
    
                                if (group == null)
                                    group = CreateRecipeGroup(recipeGroup);
    
                                recipe.Group = group;
                                break;
                        }
                    }
    
                    if (group != null)
                        group.Items.Add(recipe);
                }
            }
            
            private static RecipeDataGroup CreateRecipeGroup(JsonObject obj)
            {
                RecipeDataGroup group = new RecipeDataGroup();
    
                foreach (var key in obj.Keys)
                {
                    IJsonValue val;
                    if (!obj.TryGetValue(key, out val))
                        continue;
    
                    switch (key)
                    {
                        case "key":
                            group.UniqueId = val.GetString();
                            break;
                        case "title":
                            group.Title = val.GetString();
                            break;
                        case "shortTitle":
                            group.ShortTitle = val.GetString();
                            break;
                        case "description":
                            group.Description = val.GetString();
                            break;
                        case "backgroundImage":
                            group.SetImage(val.GetString());
                            break;
                        case "groupImage" :
                            group.SetGroupImage(val.GetString());
                            break; 
                    }
                }
    
                _recipeDataSource.AllGroups.Add(group);
                return group;
            }
        }
    }
    

    Sunday, November 17, 2013 9:15 PM

Answers

  • That will generate an stub BindableBase. You'd still have to implement the code. You can install different VS versions side by side with no problem. I do that all the time.

    If you generate a template app on 2012 it will have the 2012 files such as BindableBase. These will mostly still work in 2013 even though the 2013 templates don't have them. The caveat is that they will require changes to migrate to Windows 8.1 if you are using VS2013 express, since express doesn't support Windows 8 apps.

    End story, for a first app use a tutorial which matches the version of Visual Studio you are using. For a later apps you can learn a lot by figuring out the upgrade.

    --Rob

    • Marked as answer by Anne Jing Tuesday, November 26, 2013 8:03 AM
    Monday, November 18, 2013 3:25 PM
    Moderator

All replies

  • create new grid application. the bindablebase will be in there

    Microsoft Certified Solutions Developer - Windows Store Apps Using C#

    Sunday, November 17, 2013 10:25 PM
  • Dave,

    This project was a new Grid Application.  The code above comes from my RecipeDataSource.cs file.  I tried creating a new Item and copying the code into the new file, but hot the same results.  So I'm not sure I fully understand your suggestion.  Thanks.

    Kevin

    Sunday, November 17, 2013 11:31 PM
  • Hi Kevin,

    Your suspicion is correct. BindableBase is in the Visual Studio 2012 templates but not in the Visual Studio 2013 templates. You will need to follow a tutorial designed for Visual Studio 2013, get the files from Visual Studio 2012 (the BindableBase class should still work), or implement your own similar class.

    --Rob

    • Proposed as answer by Dave SmitsMVP Monday, November 18, 2013 1:53 PM
    Monday, November 18, 2013 2:16 AM
    Moderator
  • Rob,

    I will see if there is an updated tutorial for VS2013.  When you say get the files from VS2012, what exactly do you mean?  The RecipeDataSource.cs was imported and I believe it was from 2012.  Also, implementing my own similar class is a way over my head at this time. :-)  Thanks.

    Kevin

    Monday, November 18, 2013 1:27 PM
  • Rob,

    I noticed that in the VS IDE intellisense give me as option to Generate class for 'BindableBase' or Generate new type.  Will either get me past this?  Or, should I just go with VS 2012 to get through the tutorial?  Can VS 2012 and 2013 co-exist?

    Kevin

    Monday, November 18, 2013 1:59 PM
  • That will generate an stub BindableBase. You'd still have to implement the code. You can install different VS versions side by side with no problem. I do that all the time.

    If you generate a template app on 2012 it will have the 2012 files such as BindableBase. These will mostly still work in 2013 even though the 2013 templates don't have them. The caveat is that they will require changes to migrate to Windows 8.1 if you are using VS2013 express, since express doesn't support Windows 8 apps.

    End story, for a first app use a tutorial which matches the version of Visual Studio you are using. For a later apps you can learn a lot by figuring out the upgrade.

    --Rob

    • Marked as answer by Anne Jing Tuesday, November 26, 2013 8:03 AM
    Monday, November 18, 2013 3:25 PM
    Moderator
  • I stumbled on the same issue, and i'm trying to recreate the class of contoso cookbook, i believe it will give more baggage.
    Sunday, March 16, 2014 10:26 PM
  • I got the same problem working through another Windows 8 sample in Visual Studio 2013.

    It's an obsolete implementation of a ViewModel. 

    I fixed it by just implementing the interface INotifyPropertyChanged (instead of BindableBase) and then supporting this in the VM:

    using System.ComponentModel;
    
    namespace HostApp
    {
        public class MainPageViewModel : INotifyPropertyChanged /* In place of `BindableBase */
        {
           ...
             private int roasted = 400; // Sample VM property
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            /// Gets or sets the sample property
    public int Roasted
            {
                get { return this.roasted; }
                set {  this.toasted = value; PropertyChanged(this, new PropertyChangedEventArgs("Roasted")); }
            }
    
         }
    }

    Or you can use whatever VM framework or utility you like.





    • Edited by BorisAdams Monday, August 11, 2014 4:19 AM
    Monday, August 11, 2014 4:14 AM