简体   繁体   中英

Set DataContext into userControl

I have created MainWindow as a 'MasterPage' and inside this window I want to switch between other views which are UserControls. Inside MainViewModel which is DataContext of MainWindow I have created ObservableCollection as my 'pages'. Here is my XAML of view changes:

<UserControl Grid.Row="1" Content="{Binding CurrentView.Content}"/>

View changing is working as expected but CurrentView still has MainWindow`s DataContext even when I set DataContext inside specific UserControl as example:

<UserControl.DataContext>
        <viewModels:DesignerViewModel/>
</UserControl.DataContext>

You can use Prism framework for this issue. He can navigate your content control between your user controls easily.

https://github.com/PrismLibrary/Prism-Samples-Wpf

I used a TabControl to switch between UserControls see below XAML:

<TabControl Grid.Row="1" Margin="5" Name="tabControl" SelectionChanged="tabControl_SelectionChanged">
       <TabItem IsSelected="True" FontSize="20">
           <TabItem.Header>
               <StackPanel Orientation="Horizontal">
                   <Image Source="/Images/basket.png" Width="20" Height="20" Margin="0,0,5,0"/>
                   <TextBlock Text="Orders" VerticalAlignment="Center" />
               </StackPanel>
           </TabItem.Header>
           <UserControl Name="ucOrder" />
       </TabItem>
       <TabItem IsSelected="True" FontSize="20">
            <TabItem.Header>
               <StackPanel Orientation="Horizontal">
                   <Image Source="/Images/report.png" Width="20" Height="20" Margin="0,0,5,0"/>
                   <TextBlock Text="Order Reports" VerticalAlignment="Center" />
               </StackPanel>
            </TabItem.Header>
            <UserControl Name="ucReports" />
       </TabItem>                
</TabControl>

As you can see i have some text and images included in the tabitem aswell, i just want you to notice the Usercontrol in each of them.

You need to create a UserControl, like this:

<UserControl x:Class="Order.ucOrderOversigt"
             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="600" Loaded="UserControl_Loaded" Unloaded="UserControl_Unloaded">
    <UserControl.Resources>
        <!-- Resources -->
    </UserControl.Resources>
    <Grid >
        <!-- GUI-->
    </Grid>
</UserControl> 

And the following .cs code:

namespace WPFBestilling.Order
{
    public partial class ucOrderOversigt: UserControl
    {

        public ucOrderOversigt()
        {
            //constructor
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
           //Loaded
        }

        private void UserControl_Unloaded(object sender, RoutedEventArgs e)
        {
            //Unloaded
        }
    }
}

Then lastly to switch between the tabs in the main window, you need some .cs code to do so. Like this:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            ucOrder.Content = new ucOrderOversigt();            
            ucReports.Content = new ucReportOversigt();            
        }

        private void tabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //if something needs to happend when you shift between tabs
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            //Window closing
        }
    }

I hope it helps, if you have any questions just shoot :)

You should set the CurrentView property to an instance of a view model and use a ContentControl to display and map a view with a view model, eg:

<ContentControl Content="{Binding Binding CurrentView}">
    <ContentControl.Resources>
        <DataTemplate DataType="local:DesignerViewModel">
            <local:DesignerUserControl />
        </DataTemplate>
        <DataTemplate DataType="local:TypeBViewModel">
            <local:TypeBUserControl />
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>

The type of the CurrentView should either be a common base type for all the view models or object .

You then define a DataTemplate per view model type like above and remove this from the UserControls :

<UserControl.DataContext>
    <viewModels:DesignerViewModel/>
</UserControl.DataContext>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM