Retaining data on other tabs?

Jan 4, 2014 at 10:10 PM
Hi all,

I apologize in advance if this is a stupidly easy question. I tried searching but I'm not entirely sure what I'm searching for which makes it difficult.

Effectively, I have a MainWindow. It's source is set to Config.xaml:
<UserControl
             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" 
             xmlns:mui="http://firstfloorsoftware.com/ModernUI"
             xmlns:Content="clr-namespace:DeployWiz.Content" x:Class="DeployWiz.Pages.Config"
             mc:Ignorable="d" 
             d:DesignHeight="356.978" d:DesignWidth="333.582">
    <Grid Style="{StaticResource ContentRoot}" Margin="16,28,16,5">
        <mui:ModernTab Layout="List" SelectedSource="/Content/Info.xaml" Margin="0,0,0,40">
            <mui:ModernTab.Links>
                <mui:Link DisplayName="Settings" Source="/Content/Info.xaml" />
                <mui:Link DisplayName="Applications" Source="/Content/Applications.xaml" />
            </mui:ModernTab.Links>
        </mui:ModernTab>
        <Button Content="Start" HorizontalAlignment="Center" Margin="0,0,0,5" VerticalAlignment="Bottom" Width="75" Click="Button_Click"/>
    </Grid>

</UserControl>
The info and application pages both have a set of text and checkboxes. When I click Start on the config page I want to be able to get their values and do things with it.

I'm extremely new to C#, I feel like I'm missing something obvious here. If anyone has an tips or suggestions on how to accomplish this it would be most appreciated. Thanks in advance for the help!
Jan 8, 2014 at 1:49 AM
I rewrote my whole program to use MVVM since it seemed to me like that was going to be a step in the right direction. I still have the exact same problem though. The config page and the settings page both need to access the view model. They both create their own instances so the changes that occur on the settings page are irrelevant when the start button is clicked.

Please help me! :'(
Jan 8, 2014 at 10:24 AM
Hi,

I am in the process of developing an application using MUI where I needed to achieve something similar. I have a number of views all backed by ViewModels that need to pass data around and/or potentially access the same "persistent" data.

I decided the neatest solution was to create a "controlling" class that contained public properties that exposed instances of my ViewModel classes (and other properties). This controlling class was then specified as a public property on the application class itself (added on app.xaml.cs) making it accessible from anywhere and everywhere and was instantiated when the application opens, ensuring it was available and persistent for the lifetime of the session.

When I wanted to use the same instance of a ViewModel between views rather than separate instances, I implemented the IContent interface on my View(s), this allows you to code a number of methods that are triggered when navigating to/from said view. I coded up the navigate to method so that the views ViewModel/Datacontext was set to the appropriate ViewModel property on the instance of the controlling class (which on the first pass would replace the instance of the ViewModel the view created when it was first created).

Unfortunately I don't have the code to hand to provide examples, but happy to provide an example if needed.

It may not follow the "MVVM" rules rigidly or be the absolute best solution, but it was neat enough for what I am developing and more importantly it worked :-)

Ants
Jan 8, 2014 at 2:56 PM
Hello,
just set the DataContext of the ViewModel to the Mainpage with the ModernTabs.
Then you can bind your settings from the Usercontrolls to the same instance of the ViewModel
and use it in all UserControlls below the MainPage.

greets
Jan 8, 2014 at 4:17 PM
Edited Jan 8, 2014 at 4:18 PM
AntsInYaPants wrote:
It may not follow the "MVVM" rules rigidly or be the absolute best solution, but it was neat enough for what I am developing and more importantly it worked :-)
I wouldn't suggest this as being "neat" ;)

Understanding the MVVM design pattern and properly implementing it will be worth while and save you lots of headaches in the future. I use mvvm light for a light weight MVVM framework that provides services that will let your view models communicate in a loosely coupled manner (messages). It also has the the concept of a ViewModelLocator that is similar to your "Controlling" class, but is much cleaner than being exposed by the Application object.

Also check out dependency injection / IoC. It will solve the issue of how/when your ViewModels are resolved and how they can be cleanly accessed. For this, I use Microsoft's unity even though mvvm light does offer its own IoC.

In either case, none of these questions are MUI specific and don't really belong in these forums.
Jan 8, 2014 at 5:50 PM
SnuSnu wrote:
Hello,
just set the DataContext of the ViewModel to the Mainpage with the ModernTabs.
Then you can bind your settings from the Usercontrolls to the same instance of the ViewModel
and use it in all UserControlls below the MainPage.
Can you elaborate on that just a bit or maybe show me an example? This sounds like it would be the best solution in my case but I'm not entirely sure how that would work. The page with the ModernTabs is what I posted above. So I should set the DataContext of the ViewModel to point to that page? How would the tabs be bound to the same instance of the ViewModel at that point?

flyte wrote:
In either case, none of these questions are MUI specific and don't really belong in these forums.
I suppose this is technically true, sorry about that. Since I was using ModernUI this is just where I came by default. I'll be more mindful of that next time if I hit another road block.
Jan 9, 2014 at 6:46 AM
Edited Jan 9, 2014 at 6:47 AM
Can you elaborate on that just a bit or maybe show me an example? This sounds like it would be the best solution in my case but I'm not entirely sure how that would work. The page with the ModernTabs is what I posted above. So I should set the DataContext of the ViewModel to point to that page? How would the tabs be bound to the same instance of the ViewModel at that point?
Just reference the ViewModel (in example "allgemein:Adressen") to the XAML.
A UserControl in a UserControl/Window get its DataContext from his Parent-Control:
<UserControl x:Class="licpsa_desktopclient.Views.Allgemein.Adressen.frmAdressen"
             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" 
             xmlns:mui="http://firstfloorsoftware.com/ModernUI"
             xmlns:resx="clr-namespace:licpsa_desktopclient.Properties.Languages"
             xmlns:allgemein="clr-namespace:licpsa_desktopclient.Controller.Allgemein"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    
    <UserControl.DataContext>
        <allgemein:Adressen/>
    </UserControl.DataContext>
    
    <Grid Style="{StaticResource ContentRoot}" 
          Margin="0,28,0,0">
        <mui:ModernTab SelectedSource="{Binding SelectedSource, Mode=TwoWay}" 
                       Layout="Tab">
            <mui:ModernTab.Links>
                <mui:Link DisplayName="{x:Static resx:Default.default_search}" 
                          Source="/Views/Allgemein/Adressen/frmAdressenSuche.xaml" />
                <mui:Link DisplayName="{x:Static resx:Default.default_result}" 
                          Source="/Views/Allgemein/Adressen/frmAdressenErgebnis.xaml" />
                <mui:Link DisplayName="{x:Static resx:Default.default_detail}" 
                          Source="/Views/Allgemein/Adressen/frmAdressenDetail.xaml" />
            </mui:ModernTab.Links>
        </mui:ModernTab>
    </Grid>
    
</UserControl>
Then, for example in "frmAdressenSuche.xaml" (AddressSearch), you can access a DepencyProperty from the ViewModel and bind it to a Label/Textbox/...
<UserControl
    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"
    xmlns:mui="http://firstfloorsoftware.com/ModernUI"
    xmlns:validators="clr-namespace:licpsa_desktopclient.Classes"
    xmlns:resx="clr-namespace:licpsa_desktopclient.Properties.Languages"
    x:Class="licpsa_desktopclient.Views.Allgemein.Adressen.frmAdressenSuche"
    mc:Ignorable="d" 
    d:DesignHeight="600" 
    d:DesignWidth="600">

    <Grid Style="{StaticResource ContentRoot}">
        <Label Content="{Binding YourProperty}"/>
...
If you need to set the Content of the Label by the ViewModel, you have to set a Two-Way Binding like "{Binding YourProperty, Mode=TwoWay}"

Hope this helps you a lot ;)
greets
Jan 9, 2014 at 5:43 PM
You're the best! That's exactly what I wanted!
Jan 10, 2014 at 9:04 AM
Homeskewld wrote:
You're the best! That's exactly what I wanted!
no problem, if you have any other trouble, feel free to send me a mail... if you forgive me my bad english ;)