Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. WPF
  4. Accessing function on Usercontrol hosted from Window in MVVM and C#

Accessing function on Usercontrol hosted from Window in MVVM and C#

Scheduled Pinned Locked Moved WPF
questioncsharpwpfarchitectureannouncement
16 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S SledgeHammer01

    Haha... yeah, MVVM is a learning curve on top of the WPF learning curve. Trust me though, I come from the MFC / C++ world and did a bit of time in the C# / Winforms world... the WPF / MVVM way is by far the best. It results in *really* clean code. Anyways... Your data structure should kind of try to closely mirror how you want it in the tree. Obviously we aren't going to be modifying the alphabet any time soon, so we have 26 root nodes. I'd probably try to store it in something like: public class ContactCollection : ObservableCollection<Contact> The reason you need to do that is because XAML doesn't work well with generics. SortedDictionary<char, ContactCollection> so you'll populate the sorted dictionary with keys 'A' through 'Z' and new up an ContactCollection as the value. Then populate each ContactCollection with the names matching that letter. There is a little known trick to sort the ObservableCollections after you populate them. You derive a class from ObservableCollection and add a method like this:

    public void Sort(Comparison<T> comparison)
    {
    ((List<T>)Items).Sort(comparison);
    OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    Then your HierachialDataTemplate would just specify Key as the top level display binding and Values as the ItemsSource. Another HierachialDataTemplate would be typed for Contact and have the name as the display value. This all might not make sense now, but once you get going, it will.

    A Offline
    A Offline
    Alisaunder
    wrote on last edited by
    #7

    Kind of understand some but still confused. Below is the class I'm constructing

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;

    namespace Manufactured_Housing_Manager
    {
    public class ContactCollection : ObservableCollection
    {
    #region left, right, mid string functions

        public static string left(string param, int length)
        {
            //we start at 0 since we want to get the characters starting from the
            //left and with the specified length and assign it to a variable
            string result = param.Substring(0, length);
            //return the result of the operation
            return result;
        }
    
        public static string mid(string param, int startIndex, int length)
        {
            //start at the specified index in the string and get the number of
            //characters depending on the length and assign it to a variable
            string result = param.Substring(startIndex, length);
            //return the result of the operation
            return result;
        }
    
        public static string right(string param, int length)
        {
            //start at the index based on the length of the string minus
            //the specified length and assign it a variable
            string result = param.Substring(param.Length - length, length);
            //return the result of the operation
            return result;
        }
    
        #endregion
    
         public ContactCollection() : base()
         {
             Add(new Contact("Davis, Adam T.", 0));
             Add(new Contact("Zappa, Frank M.", 1));
             Add(new Contact("Henry, Victor", 2));
             Add(new Contact("Vern, Jules W.", 3));
         }
    
    }
    
     public class Contact
     {
         private string \_name;
         private int \_id;
         public string Name
         {
             get { return \_name; }
             set { \_name = value; }
         }
    
         public int Id
         {
             get { return \_id; }
             set { \_id = value; }
         }
    
         public Contact()
         {
         }
    
         public Contact(string name, int id)
         {
             \_name = name;
             \_id = id;
         }
     }
    

    }

    Thing is I need to open my OLEDB Database to populate my dataset then I populate ObservableCollection with the names from each Contact in

    S 1 Reply Last reply
    0
    • A Alisaunder

      Kind of understand some but still confused. Below is the class I'm constructing

      using System;
      using System.Collections.Generic;
      using System.Collections.ObjectModel;
      using System.Linq;
      using System.Text;

      namespace Manufactured_Housing_Manager
      {
      public class ContactCollection : ObservableCollection
      {
      #region left, right, mid string functions

          public static string left(string param, int length)
          {
              //we start at 0 since we want to get the characters starting from the
              //left and with the specified length and assign it to a variable
              string result = param.Substring(0, length);
              //return the result of the operation
              return result;
          }
      
          public static string mid(string param, int startIndex, int length)
          {
              //start at the specified index in the string and get the number of
              //characters depending on the length and assign it to a variable
              string result = param.Substring(startIndex, length);
              //return the result of the operation
              return result;
          }
      
          public static string right(string param, int length)
          {
              //start at the index based on the length of the string minus
              //the specified length and assign it a variable
              string result = param.Substring(param.Length - length, length);
              //return the result of the operation
              return result;
          }
      
          #endregion
      
           public ContactCollection() : base()
           {
               Add(new Contact("Davis, Adam T.", 0));
               Add(new Contact("Zappa, Frank M.", 1));
               Add(new Contact("Henry, Victor", 2));
               Add(new Contact("Vern, Jules W.", 3));
           }
      
      }
      
       public class Contact
       {
           private string \_name;
           private int \_id;
           public string Name
           {
               get { return \_name; }
               set { \_name = value; }
           }
      
           public int Id
           {
               get { return \_id; }
               set { \_id = value; }
           }
      
           public Contact()
           {
           }
      
           public Contact(string name, int id)
           {
               \_name = name;
               \_id = id;
           }
       }
      

      }

      Thing is I need to open my OLEDB Database to populate my dataset then I populate ObservableCollection with the names from each Contact in

      S Offline
      S Offline
      SledgeHammer01
      wrote on last edited by
      #8

      Ok, so your ROOT object is going to be a:

      SortedDictionary<char, ContactCollection>

      So you would do something like:

      SortedDictionary<char, ContactCollection> dict = new SortedDictionary();

      for (int i = System.Convert.ToInt32('A'); i <= System.Convert.ToInt32('Z'); i++)
      {
      ContactCollection cc = new ContactCollection();

      // add contacts with the last name starting with i to cc here
      foreach (...)
      {
      }

      dict.Add(System.Convert.ToChar(i), cc);
      }

      tv.ItemsSource = dict;

      Your contact object also needs to implement INotifyPropertyChanged for this all to work correctly. Report what your tree looks like on the screen and we can tweak the HierarchialDataTemplate to display the right content.

      A 2 Replies Last reply
      0
      • S SledgeHammer01

        Ok, so your ROOT object is going to be a:

        SortedDictionary<char, ContactCollection>

        So you would do something like:

        SortedDictionary<char, ContactCollection> dict = new SortedDictionary();

        for (int i = System.Convert.ToInt32('A'); i <= System.Convert.ToInt32('Z'); i++)
        {
        ContactCollection cc = new ContactCollection();

        // add contacts with the last name starting with i to cc here
        foreach (...)
        {
        }

        dict.Add(System.Convert.ToChar(i), cc);
        }

        tv.ItemsSource = dict;

        Your contact object also needs to implement INotifyPropertyChanged for this all to work correctly. Report what your tree looks like on the screen and we can tweak the HierarchialDataTemplate to display the right content.

        A Offline
        A Offline
        Alisaunder
        wrote on last edited by
        #9

        One last problem I think. How do I get tv.ItemsSource = dict; to work. I get, An object reference is required for the non-static field, method, or property 'Manufactured_Housing_Manager.Outlookbar.MyTreeView' I tried adding this to the tope of this class using tv = Manufactured_Housing_Manager.Outlookbar; also this is my xaml for binding it's inside Outlookbar.xaml

        modified on Friday, August 12, 2011 7:49 PM

        A 1 Reply Last reply
        0
        • A Alisaunder

          One last problem I think. How do I get tv.ItemsSource = dict; to work. I get, An object reference is required for the non-static field, method, or property 'Manufactured_Housing_Manager.Outlookbar.MyTreeView' I tried adding this to the tope of this class using tv = Manufactured_Housing_Manager.Outlookbar; also this is my xaml for binding it's inside Outlookbar.xaml

          modified on Friday, August 12, 2011 7:49 PM

          A Offline
          A Offline
          Alisaunder
          wrote on last edited by
          #10

          I know I'm over thinking this. The whole Observable Collections thing is new to me. I'm confusing myself and getting discouraged. I created a hierarchical observable collection that worked before. but populating the class with data from my user selected OLE database was done outside the class. I can vaguely see how this is supposed to work , I'm just not visualizing the code to make it happen very well. All of you help has been and is appreciated.

          S 1 Reply Last reply
          0
          • A Alisaunder

            I know I'm over thinking this. The whole Observable Collections thing is new to me. I'm confusing myself and getting discouraged. I created a hierarchical observable collection that worked before. but populating the class with data from my user selected OLE database was done outside the class. I can vaguely see how this is supposed to work , I'm just not visualizing the code to make it happen very well. All of you help has been and is appreciated.

            S Offline
            S Offline
            SledgeHammer01
            wrote on last edited by
            #11

            I was just showing you what property you needed to set. In proper MVVM, you don't set the ItemsSource explicitly. You just return it from your ViewModel. public SortedDictionary> ItemsSource { get { if (_dict == null) { // create the dictionary and observable collections here and // store in _dict } return _dict; } then your XAML's DataContext should point to your ViewModel. Then you can just do: and your tree should be built for you.

            A 1 Reply Last reply
            0
            • S SledgeHammer01

              I was just showing you what property you needed to set. In proper MVVM, you don't set the ItemsSource explicitly. You just return it from your ViewModel. public SortedDictionary> ItemsSource { get { if (_dict == null) { // create the dictionary and observable collections here and // store in _dict } return _dict; } then your XAML's DataContext should point to your ViewModel. Then you can just do: and your tree should be built for you.

              A Offline
              A Offline
              Alisaunder
              wrote on last edited by
              #12

              You were talking about my needing to implement INotifyPropertyChanged, I've tried to use this before but I never was able to get it to work properly. How do you implement it and respond to it? I know that if I add or remove an item from my collection it will flag the INotifyPropertyChanged event. and I know that if I setup a function to respond to this it will run the code within it. But how do I use it actually?

              S 1 Reply Last reply
              0
              • A Alisaunder

                You were talking about my needing to implement INotifyPropertyChanged, I've tried to use this before but I never was able to get it to work properly. How do you implement it and respond to it? I know that if I add or remove an item from my collection it will flag the INotifyPropertyChanged event. and I know that if I setup a function to respond to this it will run the code within it. But how do I use it actually?

                S Offline
                S Offline
                SledgeHammer01
                wrote on last edited by
                #13

                If you use ObservableCollection, that already implements INotifyCOLLECTIONChanged for you. That will automatically update the UI when an item is added or removed. Your Contact object needs to implement INotifyPROPERTYChanged so the UI knows when a property of the contact object has changed. See this for a basic example: http://msdn.microsoft.com/en-us/library/ms229614.aspx[^]. For both INotifyPropertyChanged and INotifyCollectionChanged, you do not need to do anything else beyond implement the interfaces. When you bind to stuff, the WPF infrastructure will subscribe to the necessary events and do its thing for you.

                A 1 Reply Last reply
                0
                • S SledgeHammer01

                  If you use ObservableCollection, that already implements INotifyCOLLECTIONChanged for you. That will automatically update the UI when an item is added or removed. Your Contact object needs to implement INotifyPROPERTYChanged so the UI knows when a property of the contact object has changed. See this for a basic example: http://msdn.microsoft.com/en-us/library/ms229614.aspx[^]. For both INotifyPropertyChanged and INotifyCollectionChanged, you do not need to do anything else beyond implement the interfaces. When you bind to stuff, the WPF infrastructure will subscribe to the necessary events and do its thing for you.

                  A Offline
                  A Offline
                  Alisaunder
                  wrote on last edited by
                  #14

                  This is what I came up with

                  using System;
                  using System.Data;
                  using System.Collections.Generic;
                  using System.Collections.ObjectModel;
                  using System.ComponentModel;
                  using System.Linq;
                  using System.Text;

                  namespace Manufactured_Housing_Manager
                  {
                  public class Contact : INotifyPropertyChanged
                  {
                  private string _name = String.Empty;
                  private int _id = 0;

                      public event PropertyChangedEventHandler PropertyChanged;
                      private void NotifyPropertyChanged(String info)
                      {
                          if (PropertyChanged != null)
                          {
                              PropertyChanged(this, new PropertyChangedEventArgs(info));
                          }
                      }  
                  
                      public string Name
                      {
                          get { return this.\_name; }
                  
                          set
                          {
                              if (value != this.\_name)
                              {
                                  this.\_name = value;
                                  NotifyPropertyChanged("Name");
                              }
                          }  
                      }
                  
                      public int Id
                      {
                          get { return this.\_id; }
                          
                          set
                          {
                              if (value != this.\_id)
                              {
                                  this.\_id = value;
                                  NotifyPropertyChanged("Id");
                              }
                          }  
                      }
                  
                      public Contact()
                      {
                      }
                  
                      public Contact(string name, int id)
                      {
                          \_name = name;
                          \_id = id;
                      }
                  } 
                  

                  }

                  My Xaml code is

                  S 1 Reply Last reply
                  0
                  • A Alisaunder

                    This is what I came up with

                    using System;
                    using System.Data;
                    using System.Collections.Generic;
                    using System.Collections.ObjectModel;
                    using System.ComponentModel;
                    using System.Linq;
                    using System.Text;

                    namespace Manufactured_Housing_Manager
                    {
                    public class Contact : INotifyPropertyChanged
                    {
                    private string _name = String.Empty;
                    private int _id = 0;

                        public event PropertyChangedEventHandler PropertyChanged;
                        private void NotifyPropertyChanged(String info)
                        {
                            if (PropertyChanged != null)
                            {
                                PropertyChanged(this, new PropertyChangedEventArgs(info));
                            }
                        }  
                    
                        public string Name
                        {
                            get { return this.\_name; }
                    
                            set
                            {
                                if (value != this.\_name)
                                {
                                    this.\_name = value;
                                    NotifyPropertyChanged("Name");
                                }
                            }  
                        }
                    
                        public int Id
                        {
                            get { return this.\_id; }
                            
                            set
                            {
                                if (value != this.\_id)
                                {
                                    this.\_id = value;
                                    NotifyPropertyChanged("Id");
                                }
                            }  
                        }
                    
                        public Contact()
                        {
                        }
                    
                        public Contact(string name, int id)
                        {
                            \_name = name;
                            \_id = id;
                        }
                    } 
                    

                    }

                    My Xaml code is

                    S Offline
                    S Offline
                    SledgeHammer01
                    wrote on last edited by
                    #15

                    I have told you how a few times now :) and even gave you the code last time. You need to have *26* ObservableCollection's. Your *ROOT* object needs to be a SortedDictionary>. You will insert 26 entries into the sorted dictionary. Key is 'A' - 'Z' and the value is a new ObservableCollection that contains the last names starting with that key.

                    1 Reply Last reply
                    0
                    • S SledgeHammer01

                      Ok, so your ROOT object is going to be a:

                      SortedDictionary<char, ContactCollection>

                      So you would do something like:

                      SortedDictionary<char, ContactCollection> dict = new SortedDictionary();

                      for (int i = System.Convert.ToInt32('A'); i <= System.Convert.ToInt32('Z'); i++)
                      {
                      ContactCollection cc = new ContactCollection();

                      // add contacts with the last name starting with i to cc here
                      foreach (...)
                      {
                      }

                      dict.Add(System.Convert.ToChar(i), cc);
                      }

                      tv.ItemsSource = dict;

                      Your contact object also needs to implement INotifyPropertyChanged for this all to work correctly. Report what your tree looks like on the screen and we can tweak the HierarchialDataTemplate to display the right content.

                      A Offline
                      A Offline
                      Alisaunder
                      wrote on last edited by
                      #16

                      Thanks for all the help I have it working now! :)

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups