none
Show Correct Usercontrol based on Selection

    Question

  • Goal:
    When you click one of the button from the usercontrol_menu the current and displayed usercontrol will be removed or invisible. A new usercontrol, based on the selection, will be displayed.


    The main problem is:
    - How to change the usercontrol (Candy, computer, happy) after clicking the button from the usercontrol menu?

    There are three sub problems I'm facing.

    1.
    What part am I missing in order to make the for instance user control candy visible after clicking in the button from the usercontrol menu?

    2.
    What syntax do I need to use bind in order make the button from usercontrol menu to be bind to the code "{Binding Selected, UpdateSourceTrigger=PropertyChanged}"?

    3.
    What syntax do I need to use bind in order make the button from usercontrol menu to be bind to the code "{Binding Selected, UpdateSourceTrigger=PropertyChanged}"? I'm not sure if I'm doing right.

    Information:

    1. You display one usercontrol (candy, computer, happy) at a time.

    2.The usercontrol (candy, computer, happy) shall have same position.

    3. Full access to the source code "https://github.com/sakuradata/aaa".

    <UserControl x:Class="menu.UserControl1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" Height="78" Width="647">
        <Grid Background="#FFABCD79">
    
            <Button Content="{Binding Selected, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="73,33,0,0" VerticalAlignment="Top" Width="75" Height="20"/>
            <Button Content="Computer" HorizontalAlignment="Left" Margin="195,33,0,0" VerticalAlignment="Top" Width="75"/>
            <Button Content="Happy" HorizontalAlignment="Left" Margin="319,33,0,0" VerticalAlignment="Top" Width="75"/>
        </Grid>
    </UserControl>
    
    
    --------------------------
    
    <UserControl x:Class="candy.UserControl1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 Height="78" Width="647"  >
        <Grid Background="#FF9297BB">
    
    
        </Grid>
    </UserControl>
    
    
    --------------------------
    
    
    <Window 
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:menu="clr-namespace:menu;assembly=menu" 
            xmlns:computer="clr-namespace:computer;assembly=computer" 
            xmlns:candy="clr-namespace:candy;assembly=candy" 
            x:Class="aaa.MainWindow"
            Title="MainWindow" Height="395" Width="763"
    	    xmlns:local="aaa"     
    
    >
        <Grid>
    <menu:UserControl1 Margin="56,39,52,247" />
            
            
            <ContentControl Content="{Binding Selected}">
                <ContentControl.Resources>
                    <DataTemplate DataType="computer:ComputerViewModel">
                        <computer:UserControl1 />
                    </DataTemplate>
    
                    <DataTemplate DataType="candy:CandyViewModel">
                        <candy:UserControl1 />
                    </DataTemplate>
                </ContentControl.Resources>
            </ContentControl>
    
        </Grid>
    </Window>
    
    
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace aaa
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
               // this.DataContext = new MainViewModel();
            }
        }
    
    
        internal class MainViewModel : INotifyPropertyChanged
        {
            public MainViewModel()
            {
                //subscribe to some message and set the value of the Selected property here...
            }
    
            private BaseClass _selected;
    
            public BaseClass Selected
            {
                get { return _selected; }
                set
                {
                    _selected = value;
                    NotifyPropertyChanged("Selected");
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    
        public class BaseClass
        {
        }
    
        public class CandyViewModel : BaseClass
        {
    
        }
    
        public class ComputerViewModel : BaseClass
        {
    
        }
    
    }


    • Edited by Sakura Data Thursday, July 03, 2014 7:30 PM
    Thursday, July 03, 2014 3:11 PM

Answers

  • Change the viewmodel for the menu:

            public UserControl ComputerUC
            {
                get
                {
                    if (computerUC == null)
                    {
                        computerUC = new computer.UserControl1() as UserControl;
                        ExecuteUCCommand(computerUC);
                    }
                    return computerUC;
                }
                set { computerUC = value; }
            }

    Please don't forget to mark posts which help and or answer your questions.
    • Edited by Andy ONeill Sunday, July 06, 2014 8:48 AM
    • Marked as answer by Sakura Data Sunday, July 06, 2014 10:46 AM
    Sunday, July 06, 2014 8:46 AM

All replies

  • I don't think this is a great way to go.

    The applications which I have (live) do this using messenger to talk across layers.

    The mainwindow subscribes to that message and swaps out the content of a frame in code.


    • Edited by Andy ONeill Thursday, July 03, 2014 3:41 PM
    Thursday, July 03, 2014 3:40 PM
  • 1. Set the DataContext of the MainWindow to an instance of the MainViewModel class:

    public partial class MainWindow : Window
     {
      public MainWindow()
      {
       InitializeComponent();
       this.DataContext = new MainViewModel();
      }
     }

    2. Install MVVMLight by executing the following command in the Packade Manager Console in Visual Studio: Install-Package MvvmLight

    3. Define two commands in the MainViewModel class that sets the Selected property and bind the Buttons to these commands:

    using GalaSoft.MvvmLight.Command;
    ...
    
    internal class MainViewModel : INotifyPropertyChanged
     {
      public MainViewModel()
      {
       _computerCommand = new RelayCommand(() => { this.Selected = new ComputerViewModel(); });
       _candyCommand = new RelayCommand(() => { this.Selected = new CandyViewModel(); });
      }
    
      private RelayCommand _computerCommand;
      public RelayCommand ComputerCommand
      {
       get { return _computerCommand; }
      }
    
      private RelayCommand _candyCommand;
      public RelayCommand CandyCommand
      {
       get { return _candyCommand; }
      }
    
      private BaseClass _selected;
    
      public BaseClass Selected
      {
       get { return _selected; }
       set
       {
        _selected = value;
        NotifyPropertyChanged("Selected");
       }
      }
    
      public event PropertyChangedEventHandler PropertyChanged;
      private void NotifyPropertyChanged(string propertyName)
      {
       if (PropertyChanged != null)
       {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
       }
      }
     }
    


    <UserControl x:Class="menu.UserControl1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
     <Grid Background="#FFABCD79">
    
      <Button Content="Computer" HorizontalAlignment="Left" Margin="195,33,0,0" VerticalAlignment="Top" Width="75" Command="{Binding ComputerCommand}"/>
      <Button Content="Happy" HorizontalAlignment="Left" Margin="319,33,0,0" VerticalAlignment="Top" Width="75" Command="{Binding CandyCommand}"/>
     </Grid>
    
    </UserControl>
    

    4. Replace the Grid in the MainWindow with a StackPanel in order to locate the ContentControl that displays the currently selected user control under the menu:

    <Window x:Class="aaa.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:menu="clr-namespace:menu;assembly=menu" 
            xmlns:computer="clr-namespace:computer;assembly=computer" 
            xmlns:candy="clr-namespace:candy;assembly=candy" xmlns:aaa="clr-namespace:aaa"
            Title="MainWindow" Height="395" Width="763"
    >
     <StackPanel>
      <menu:UserControl1 />
    
    
      <ContentControl Content="{Binding Selected}">
       <ContentControl.Resources>
        <DataTemplate DataType="computer:ComputerViewModel">
         <computer:UserControl1 />
        </DataTemplate>
    
        <DataTemplate DataType="candy:CandyViewModel">
         <candy:UserControl1 />
        </DataTemplate>
       </ContentControl.Resources>
      </ContentControl>
    
     </StackPanel>
    
    </Window>
    


    Please remember to mark any helpful posts as answer and/or helpful and to close your previous threads by marking at least one of the replies as answer if helpful.

    Thursday, July 03, 2014 3:44 PM
  • The code I have to hand actually has a listview of buttons.  There are numerous options.  The listview binds to an observablecollection of NavigateViewmodel

    Plus it's Silverlight but I don't actually think that makes any difference here.

    EG the "pages" are usercontrols

            public MainViewModel(IDataService dataService)
            {
                isAdmin = (bool)Application.Current.Resources["IsAdmin"];
    
                AdminVisibility = Visibility.Collapsed;
                if (Debugger.IsAttached || isAdmin)
                {
                    AdminVisibility = Visibility.Visible;
                }
                _dataService = dataService;
                _dataService.GetData(
                    (item, error) =>
                    {
                        if (error != null)
                        {
                            // Report error here
                            return;
                        }
                    });
                setDefaultBrushes();
                Messenger.Default.Register<ActiveIncidents>(this, (action) => ReceiveActiveIncidentsMessage(action));
                Messenger.Default.Register<CommandDone>(this, (action) => ReceiveCommandDoneMessage(action));
    
    
    
                userName = Application.Current.Resources["UserName"] as string;
    
                NavigateViewModels = new ObservableCollection<NavigateViewModel>();
                BuildNavigation();
    
            }
    
             private void BuildNavigation()
            {
                NavigateViewModel defaultPage = new NavigateViewModel { Display = "Support", URI = "/SupportView.xaml", MainViewModel = this, ToPage = new SupportView() };
                NavigateViewModels.Add(defaultPage);
                NavigateViewModels.Add(new NavigateViewModel { Display = "News", URI = "/News.xaml", MainViewModel = this, ToPage = new News() });
                NavigateViewModels.Add(new NavigateViewModel { Display = "Applications", URI = "/Applications.xaml", MainViewModel = this, ToPage = new Applications() });
    
                NavigateViewModels.Add(new NavigateViewModel { Display = "FAQ", URI = "/FAQ.xaml", MainViewModel = this, ToPage = new FAQ() });
                NavigateViewModels.Add(new NavigateViewModel { Display = "Training", URI = "/TrainingView.xaml", MainViewModel = this, ToPage = new TrainingView() });
                NavigateViewModels.Add(new NavigateViewModel { Display = "Policies", URI = "/PoliciesView.xaml", MainViewModel = this, ToPage = new PoliciesView() });
    
                isEditor = (bool)Application.Current.Resources["IsEditor"];
                if (Debugger.IsAttached || isEditor || isAdmin)
                {
                    NavigateViewModels.Add(new NavigateViewModel { Display = "Editorial", URI = "/EditorialView.xaml", MainViewModel = this, ToPage = new EditorialView() });
                } 
                 
                 RaisePropertyChanged("NavigateViewModels");
    
                // Need to delay telling the mainview to navigate or the page won't be created.
                UserControl dp = defaultPage.ToPage;
                Storyboard sb = new Storyboard();
                sb.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 100));
                sb.Completed += new EventHandler(delegate(object s, EventArgs a)
                {
                    var msg = new NavigatePage { Page = dp };
                    Messenger.Default.Send<NavigatePage>(msg);
                    defaultPage.HighLightThis();
                });
                sb.Begin();
    
            }



    • Edited by Andy ONeill Thursday, July 03, 2014 4:25 PM
    Thursday, July 03, 2014 4:17 PM
  •         public MainPage()
            {
                InitializeComponent();
                Messenger.Default.Register<NavigatePage>(this, (action) => ReceiveNavigateMessage(action));
                Messenger.Default.Register<CommandDone>(this, (action) => ReceiveCommandDoneMessage(action));
                Messenger.Default.Register<Admin>(this, (action) => ReceiveAdminMessage(action));
            }
    
            private object ReceiveNavigateMessage(NavigatePage navigatePage)
            {
                this.MainPanel.Content = navigatePage.Page;
                return null;
            }

    Thursday, July 03, 2014 4:20 PM
  • Thinking about that code made me remember something.

    I never really liked the way the usercontrols were initialised in that project.

    Made me think about how I could have created the usercontrols based on a string.

    You need the fully qualified name of the usercontrol and of course if it was in a different project you'd need a reference to it in the bit of code instantiated it.

    Anhow... I did a quick and dirty experiment.

    What I'm thinking is the buttons all bind to one relaycommand with a command parameter of a fully qualified name for the usercontrol they represent.  The command just sends a message with that string in it.  You need no reference to the usercontrol in question within the menu because as far as it's concerned that command parameter is just a string.

    The subscriber uses that string to instantiate a usercontrol and stores a reference in application.current.resources so you retain state inbetween calls.  You could instead instantiate each time, obviously.

    BUT you "only" need a reference to the usercontrols in the code behind of the parent window which has the frame in it.

    I ran out of time before I could get round to doing the menu but here's my prototype code which successfully loads uc1 or uc2 depending on what I hard code into it.

    ( Don't forget the storyboard disconnecting click event from substitution ).

            public MainWindow()
            {
                InitializeComponent();
                Closing += (s, e) => ViewModelLocator.Cleanup();
                Messenger.Default.Register<SwopUserControl>(this, (action) => ReceiveSwopMessage(action));
                ReceiveSwopMessage(new SwopUserControl { fullyqualifiedUCType="WPF6.UC2"});
            }
    
            private object ReceiveSwopMessage(SwopUserControl swop)
            {
                Type UCType = Type.GetType(swop.fullyqualifiedUCType, true, true);
                UserControl uc = null;
                if (Application.Current.Resources[swop.fullyqualifiedUCType] == null)
                {
                    uc = Activator.CreateInstance(UCType) as UserControl;
                    Application.Current.Resources.Add(swop.fullyqualifiedUCType, swop.fullyqualifiedUCType);
                }
                else
                {
                    uc = Application.Current.Resources[swop.fullyqualifiedUCType] as UserControl;
                }
    
                this.UCFrame.Content = uc;
                return null;
            }

    Note, this project is called WPF6 - so that's the namespace UC1 and UC2 are in.

    Thursday, July 03, 2014 6:36 PM
  • 1.
    The instance of the usercontrol computer and candy are establish with xaml code and I wonder what code do I need to add in the class ComputerViewModel and CandyViewModel?

    2.
    I tried the source code and it displays the name of the usercontrol. How should I enable to display the usercontrol?

    3.
    "https://github.com/sakuradata/aaa" Today, you have full access to the source code.


    <Window xmlns:happy="clr-namespace:happy;assembly=happy"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:menu="clr-namespace:menu;assembly=menu" 
            xmlns:computer="clr-namespace:computer;assembly=computer" 
            xmlns:candy="clr-namespace:candy;assembly=candy" 
            x:Class="aaa.MainWindow"
            Title="MainWindow" Height="395" Width="763"
    	    xmlns:local="aaa"     
    
    >
    
        <StackPanel>
            <menu:UserControl1 Margin="56,39,52,247" />
    
    
            <ContentControl Content="{Binding Selected}">
                <ContentControl.Resources>
                    <DataTemplate DataType="computer:ComputerViewModel">
                        <computer:UserControl1 />
                    </DataTemplate>
    
                    <DataTemplate DataType="candy:CandyViewModel">
                        <candy:UserControl1 />
                    </DataTemplate>
                </ContentControl.Resources>
            </ContentControl>
    
        </StackPanel>
    
    </Window>  
    
    ----------------------
    
    using GalaSoft.MvvmLight.Command;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace aaa
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                this.DataContext = new MainViewModel();
    
            }
        }
    
    
        internal class MainViewModel : INotifyPropertyChanged
        {
            public MainViewModel()
            {
                _computerCommand = new RelayCommand(() => { this.Selected = new ComputerViewModel(); });
                _candyCommand = new RelayCommand(() => { this.Selected = new CandyViewModel(); });
            }
    
            private RelayCommand _computerCommand;
            public RelayCommand ComputerCommand
            {
                get { return _computerCommand; }
            }
    
            private RelayCommand _candyCommand;
            public RelayCommand CandyCommand
            {
                get { return _candyCommand; }
            }
    
            private BaseClass _selected;
    
            public BaseClass Selected
            {
                get { return _selected; }
                set
                {
                    _selected = value;
                    NotifyPropertyChanged("Selected");
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    
    
        public class BaseClass
        {
        }
    
        public class CandyViewModel : BaseClass
        {
    
        }
    
        public class ComputerViewModel : BaseClass
        {
    
        }
    
    
    
    }
    
    
    --------------------------
    
    
    
    
    <UserControl x:Class="menu.UserControl1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid Background="#FFABCD79">
    
            <Button Content="Computer" HorizontalAlignment="Left" Margin="195,33,0,0" VerticalAlignment="Top" Width="75" Command="{Binding ComputerCommand}"/>
            <Button Content="Candy" HorizontalAlignment="Left" Margin="319,33,0,0" VerticalAlignment="Top" Width="75" Command="{Binding CandyCommand}"/>
        </Grid>
    
    </UserControl>



    • Edited by Sakura Data Thursday, July 03, 2014 7:29 PM
    Thursday, July 03, 2014 6:57 PM
  • A message for Andy.

    1.
    In my context I dont have a "fullyqualifiedUCType" in my user control. What should I should write?

    2.
    Error message"Error    1    The name "ViewModelLocator" does not exist in the namespace "clr-namespace:aaa.ViewModel".    C:\Users\Administrator\Desktop\Andy\aaa\aaa\App.xaml    9    9    aaa
    "
    Don't know what to do? Tried to solve it but I failed.

    3.
    If you are interested in reviewing the code, you can download the source code.

    https://github.com/sakuradata2/aaa/

    using aaa.ViewModel;
    using GalaSoft.MvvmLight.Messaging;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace aaa
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                Closing += (s, e) => ViewModelLocator.Cleanup();
                Messenger.Default.Register<candy.UserControl1>(this, (action) => ReceiveSwopMessage(action));
                ReceiveSwopMessage(new candy.UserControl1 { fullyqualifiedUCType = "aaa.aaa" });
            }
    
    
    
    
            private object ReceiveSwopMessage(candy.UserControl1 swop)
            {
                Type UCType = Type.GetType(swop.fullyqualifiedUCType, true, true);
                UserControl uc = null;
                if (Application.Current.Resources[swop.fullyqualifiedUCType] == null)
                {
                    uc = Activator.CreateInstance(UCType) as UserControl;
                    Application.Current.Resources.Add(swop.fullyqualifiedUCType, swop.fullyqualifiedUCType);
                }
                else
                {
                    uc = Application.Current.Resources[swop.fullyqualifiedUCType] as UserControl;
                }
    
                this.UCFrame.Content = uc;
                return null;
            }
    
        }
    }



    • Edited by Sakura Data Thursday, July 03, 2014 10:07 PM
    Thursday, July 03, 2014 9:43 PM
  • Here's a working solution.

    This is a link:

    solution

    Note that getting instantiating usercontrols out of another dll is a complication.

    In my limited time I reverted to just instantiating one in the menu.

            private UserControl computerUC;
    
            public UserControl ComputerUC
            {
                get
                {
                    if (computerUC == null)
                    {
                        computerUC = new computer.UserControl1() as UserControl;
                    }
                    return computerUC;
                }
                set { computerUC = value; }
            }
    This is then used as a parameter to a relaycommand and sent to the parent window via messaging.

    My solution seems to work as is but I wouldn't be surprised if it had intermittent problems switching or instantiating controls and you could use code similar to the storyboard above to avoid such issues.

    Friday, July 04, 2014 7:11 AM
  • 1. The ComputerViewModel and CandyViewModel classes are the view models for the computer:UserControl1 and the candy:UserControl1 respectively. This means that you should put any properties that any elements in these user controls bind to. For example, a TextBlock in the candy:UserControl1 may bind to a string property of the CandyViewModel class:

     public class CandyViewModel : BaseClass
     {
      public string Text {
       get { return "I am a candy!"; }
      }
     }

    <UserControl x:Class="candy.UserControl1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
     <Grid Background="#FF9297BB">
      <TextBlock Text="{Binding Text}"></TextBlock>
     </Grid>
    </UserControl>

    2. Right, you need to use the x:Type syntax for the compiler to be able to understand that the string refers to a type:

      <ContentControl Content="{Binding Selected}">
       <ContentControl.Resources>
        <DataTemplate DataType="{x:Type computer:ComputerViewModel}">
         <computer:UserControl1 />
        </DataTemplate>
    
        <DataTemplate DataType="{x:Type candy:CandyViewModel}">
         <candy:UserControl1 />
        </DataTemplate>
       </ContentControl.Resources>
      </ContentControl>
    


    Please refer to the following page for more information about how to use DataTemplates with a ContentControl: http://www.japf.fr/2009/03/thinking-with-mvvm-data-templates-contentcontrol/

    Friday, July 04, 2014 8:41 AM


  • Magnus, the goal is:

    Goal:
    When you click one of the button from the usercontrol_menu the current and displayed usercontrol will be removed or invisible. A usercontrol, based on the selection, will be displayed.

    In other words, when you click on computer or candy from the user menu, the usercontrol, based the selection, shall be displayed inside of the mainwindows.

    -------------

    There is one thing I don't understand.

    What is the purpose in this context to use "  <TextBlock Text="{Binding Text}"></TextBlock>" in relation to the goal?

    Full access to the source code "https://github.com/sakuradata/aaa".
    Friday, July 04, 2014 10:16 AM
  • My solution is based on that source code.

    Have you downloaded and tried it?

    Friday, July 04, 2014 10:19 AM


  • Magnus, the goal is:

    Goal:
    When you click one of the button from the usercontrol_menu the current and displayed usercontrol will be removed or invisible. A usercontrol, based on the selection, will be displayed.

    In other words, when you click on computer or candy from the user menu, the usercontrol, based the selection, shall be displayed inside of the mainwindows.

    It will if you update the MainWindow.xaml file in the aaa project in your solution to look like this:

    <Window 
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:menu="clr-namespace:menu;assembly=menu" 
            xmlns:computer="clr-namespace:computer;assembly=computer" 
            xmlns:candy="clr-namespace:candy;assembly=candy" 
            x:Class="aaa.MainWindow"
            Title="MainWindow" Height="395" Width="763"
         xmlns:local="aaa" xmlns:aaa="clr-namespace:aaa">
    
        <StackPanel>
            <menu:UserControl1 Margin="56,39,52,247" />
    
    
            <ContentControl Content="{Binding Selected}">
                <ContentControl.Resources>
                    <DataTemplate DataType="{x:Type aaa:ComputerViewModel}">
                        <computer:UserControl1 />
                    </DataTemplate>
    
                    <DataTemplate DataType="{x:Type aaa:CandyViewModel}">
                        <candy:UserControl1 />
                    </DataTemplate>
                </ContentControl.Resources>
            </ContentControl>
    
        </StackPanel>
    
    </Window>    

    Copy and try and you will see that the UserControl shows up at the bottom when you click a Button.

    • Edited by Magnus (MM8) Friday, July 04, 2014 10:26 AM spelling
    Friday, July 04, 2014 10:24 AM
  • My solution is based on that source code.

    Have you downloaded and tried it?

    I have downloaded and tried the source code.

    I have a question.

    Is it possible to remove the red mark selection? This thing occur after two click from the usercontrol menu.

    Friday, July 04, 2014 4:34 PM
  • That bit is there because I didn't bother removing the navigation from the Frame: NavigationUIVisibility="Hidden".

    .

    The mainwindow is a bit weird though, because the window size isn't big enough to contain everything.

    I have no idea how it's really supposed to look, but..

    I think the margin around the menu is particularly strange:

            <menu:UserControl1 Margin="56,39,52,247" />

    When I remove that giving:

        <StackPanel>
            <menu:UserControl1 />
    

           

    <Framex:Name="ucFrame"NavigationUIVisibility="Hidden"/>

        </StackPanel>

    The mainwindow looks a lot more like it's a menu with some content beneath it.

    .

    The way the binding works it will immediately instantiate the two usercontrols.

    I think a slight delay on that binding is also probably advisable so the window loads before the usercontrols are instantiated.

    The modified version:

    This is a link


    • Edited by Andy ONeill Saturday, July 05, 2014 8:49 AM
    Friday, July 04, 2014 6:05 PM
  • That bit is there because I didn't bother removing the navigation from the Frame: NavigationUIVisibility="Hidden".

    .

    The mainwindow is a bit weird though, because the window size isn't big enough to contain everything.

    I have no idea how it's really supposed to look, but..

    I think the margin around the menu is particularly strange:

            <menu:UserControl1 Margin="56,39,52,247" />

    When I remove that giving:

        <StackPanel>
            <menu:UserControl1 />

           

    <Framex:Name="ucFrame"NavigationUIVisibility="Hidden"/>

        </StackPanel>

    The mainwindow looks a lot more like it's a menu with some content beneath it.

    .

    The way the binding works it will immediately instantiate the two usercontrols.

    I think a slight delay on that binding is also probably advisable so the window loads before the usercontrols are instantiated.

    The modified version:

    This is a link



    Thank you for your help! I just have one last request and I wonder how to make the usercontrol computer to be preseleced when you execute the code. In other words, when you execute the code you should enable to see usercontrol computer in the mainwindows.
    Saturday, July 05, 2014 9:19 PM
  • Change the viewmodel for the menu:

            public UserControl ComputerUC
            {
                get
                {
                    if (computerUC == null)
                    {
                        computerUC = new computer.UserControl1() as UserControl;
                        ExecuteUCCommand(computerUC);
                    }
                    return computerUC;
                }
                set { computerUC = value; }
            }

    Please don't forget to mark posts which help and or answer your questions.
    • Edited by Andy ONeill Sunday, July 06, 2014 8:48 AM
    • Marked as answer by Sakura Data Sunday, July 06, 2014 10:46 AM
    Sunday, July 06, 2014 8:46 AM