Click here to Skip to main content
15,880,469 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi, I have 1 UserControl and im using it in several Tabs, all these tabs have same parameters but i want all parameters in different tabs save data in different places. now all parameters in tabs just can save in 1 place that i have wrote in my ViewModel on the user control. Could you please help me.
here is my ViewModel()
C#
class MonitorProfileOutputViewModel:Screen
  {
     
      public string DestIP { get; set; }
      public string DestPort { get; set; }
      public string SrcPort { get; set; }
      public bool EnableProfle { get; set; }
      public bool ProfileCheck { get; set; }
      private bool checkedbox;


      public void LoadParameters()
      {
          byte[] param1 = BitConverter.GetBytes(sensor.Configuration.ProfileOutputDestinationIpHigh);
          byte[] param2 = BitConverter.GetBytes(sensor.Configuration.ProfileOutputDestinationIpLow);
          this.DestIP = Convert.ToString(param1[1]) + "." + Convert.ToString(param1[0]) + "." + Convert.ToString(param2[1]) + "." + Convert.ToString(param2[0]);
          this.DestPort = Convert.ToString(sensor.Configuration.ProfileOutputDestinationPort);
          this.SrcPort = Convert.ToString(sensor.Configuration.ProfileOutputSourcePort);
          if (sensor.Configuration.ProfileOutputStatus == 1)
              this.EnableProfile = true;
          else
              this.EnableProfile = false;

      }
      public MonitorProfileOutputViewModel()
      {
        
          LoadParameters();
      }

      public bool EnableProfile
      {
          get { return checkedbox; }
          set
          {
              checkedbox = value;
          if (value)
          {
              sensor.Configuration.ProfileOutputStatus =1;
              NotifyOfPropertyChange(() => ProfileCheck);
          }
          else
          {
              sensor.Configuration.ProfileOutputDestinationIpHigh = 0;
              sensor.Configuration.ProfileOutputDestinationIpLow = 0;
              NotifyOfPropertyChange(() => ProfileCheck);
              sensor.Configuration.ProfileOutputStatus = 0;
              NotifyOfPropertyChange(() => ProfileCheck);
          }

          }
      }

      public void Execute()
      {
          Convertions IpConverts = new Convertions();

          if (checkedbox)
          {
              sensor.Configuration.ProfileOutputDestinationPort = Convert.ToUInt16(this.DestPort);
              NotifyOfPropertyChange(() => DestIP);
              sensor.Configuration.ProfileOutputSourcePort = Convert.ToUInt16(this.SrcPort);
              NotifyOfPropertyChange(() => SrcPort);
              sensor.Configuration.ProfileOutputDestinationIpHigh = IpConverts.IPconversion(this.DestIP)[0];
              NotifyOfPropertyChange(() => DestIP);
              sensor.Configuration.ProfileOutputDestinationIpLow = IpConverts.IPconversion(this.DestIP)[1];
              NotifyOfPropertyChange(() => DestIP);
          }
          else
          {
              sensor.Configuration.ProfileOutputDestinationIpHigh = 0;
              NotifyOfPropertyChange(() => ProfileCheck);
              sensor.Configuration.ProfileOutputDestinationIpLow = 0;
              NotifyOfPropertyChange(() => ProfileCheck);
          }
      }
  }

here is my UserControl View
HTML
<UserControl x:Class="Views.MonitorProfileOutputView"
             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">
    <StackPanel>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>      
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <CheckBox  Name="ProfileCheck" Content="Enabled" Grid.Column="1" Grid.Row="0" Margin="0,0,10,5" HorizontalAlignment="Left" IsChecked="{Binding EnableProfile, Mode=TwoWay}"/>
            <TextBlock Text="Destination IP Address:" Grid.Column="0" Grid.Row="1"  Margin="0,5,5,0"/>
            <TextBlock Text="Destination Port:" Grid.Column="0" Grid.Row="2" Margin="0,5,0,0" />
            <TextBlock Text="Source Port:" Grid.Column="0" Grid.Row="3" Margin="0,5,0,0" />
            <TextBox Name="DestIP" Grid.Column="1" Grid.Row="1" Margin="0,5,0,0" Width="100" Height="20" />
            <TextBox Name="DestPort" Grid.Column="1" Grid.Row="2" Margin="0,5,0,0" Width="100" Height="20"/>
            <TextBox Name="SrcPort" Grid.Column="1" Grid.Row="3" Margin="0,5,0,0" Width="100" Height="20"/>
            <Button Name="Execute" Content="Apply"  Height="30" Width="100"  VerticalAlignment="Top"   HorizontalAlignment="Center" Margin="5,20,0,0" Grid.Row="5" Grid.Column="1">
                <Button.Effect>
                    <DropShadowEffect BlurRadius="50" ShadowDepth="0"/>
                </Button.Effect>
            </Button>
        </Grid>
    </StackPanel>
</UserControl>


this code can help for save in 1 place and i have atleast 8 tabs with same usercontrol, here is UserControl, that i make properties of my Viewmodel classes and called them like MonitorModel and ProfileModel from same UserControl(View) and now i can just save in parameters in just 1 place not different places.

HTML
<TabItem Name="ProfileOutput" Header="Profile OutPut" Margin="5"   Width="50" Height="100" HorizontalAlignment="Center" VerticalAlignment="Center"  >
                          <TabItem.Effect>
                              <DropShadowEffect
                                     ShadowDepth="5"
                                     Direction="330"
                                     Color="Black"
                                     Opacity="3"
                                     BlurRadius="4"/>
                          </TabItem.Effect>
                          <TabItem.Content>
                                  <Grid removed="DarkGray">
                                      <Grid.RowDefinitions>
                                          <RowDefinition Height="50"/>
                                          <RowDefinition/>
                                      </Grid.RowDefinitions>
                                      <Grid.ColumnDefinitions>
                                          <ColumnDefinition/>
                                          <ColumnDefinition/>
                                      </Grid.ColumnDefinitions>
                                      <StackPanel  Grid.Row="1" Grid.Column="0">
                                          <ContentControl   x:Name="ProfileModel"  VerticalAlignment="Center"  HorizontalAlignment="Left" Margin="210,20,0,0"/>
                                      </StackPanel>

                                  </Grid>
                          </TabItem.Content>
                      </TabItem>

                      <TabItem Name="MonitorOutput" Header="Monitor OutPut" Margin="5"   Width="50" Height="100" HorizontalAlignment="Center" VerticalAlignment="Center">
                          <TabItem.Effect>
                              <DropShadowEffect
                                     ShadowDepth="5"
                                     Direction="330"
                                     Color="Black"
                                     Opacity="3"
                                     BlurRadius="4"/>
                          </TabItem.Effect>
                          <TabItem.Content>
                                  <Grid removed="DarkGray">
                                      <Grid.RowDefinitions>
                                          <RowDefinition Height="50"/>
                                          <RowDefinition/>
                                      </Grid.RowDefinitions>
                                      <Grid.ColumnDefinitions>
                                          <ColumnDefinition/>
                                          <ColumnDefinition/>
                                      </Grid.ColumnDefinitions>
                                      <StackPanel  Grid.Row="1" Grid.Column="0">
                                          <ContentControl  x:Name="MonitorModel"  VerticalAlignment="Center"  HorizontalAlignment="Left" Margin="210,20,0,0"/>
                                      </StackPanel>

                                  </Grid>
                              </TabItem.Content>
                      </TabItem>
                      </TabControl>
                  </TabItem>
Posted
Updated 1-Oct-13 22:56pm
v4

1 solution

you create a tabViewModel, in the tab view model you create the collection of user control. so each control in the collection will have its own instance and be bind to each tab. This way you will maintain the separation.

App.xaml ( set the App.xaml to fire the start up event)
HTML
<Application x:Class="WPFUserControlBinding.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Startup="App_OnStartup">
    <Application.Resources>
    </Application.Resources>
</Application>

you need to set the Startup event of the App.xaml
Then edit the App.xaml.cs file as below
C#
using System.Windows;

namespace WPFUserControlBinding
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private void App_OnStartup(object sender, StartupEventArgs e)
        {
            
            var mainWindowViewModel = new MainWindowViewModel();
            var mainWindow = new MainWindow()
                {
                    DataContext = mainWindowViewModel,
                    MainTab = {DataContext = mainWindowViewModel.TabViewModel}
                };
            mainWindow.Show();
        }
    }
}


MainWindow.xaml
HTML
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPFUserControlBinding" 
        x:Class="WPFUserControlBinding.MainWindow"
        Title="MainWindow" Height="350" Width="525"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
    >
    <Window.Resources>
        <local:MainWindowViewModel x:Key="MainWindowViewModel"></local:MainWindowViewModel>
    </Window.Resources>
    <Grid d:DataContext ="{d:DesignInstance local:MainWindowViewModel}">
        <TabControl x:Name="MainTab" HorizontalAlignment="Left" Height="261" Margin="10,24,0,0" VerticalAlignment="Top" Width="460">
            <TabItem Header="TabItem1" d:DataContext="{d:DesignInstance local:TabViewModel}">
                <local:MyUserControl HorizontalAlignment="Left" Margin="32,31,0,0" VerticalAlignment="Top" Width="172" DataContext="{Binding Path=.TabItems[0]}"/>
            </TabItem>
            <TabItem Header="TabItem2" d:DataContext="{d:DesignInstance local:TabViewModel}">
                <local:MyUserControl HorizontalAlignment="Left" Margin="32,31,0,0" VerticalAlignment="Top" Width="172" DataContext="{Binding Path=.TabItems[1]}"/>
            </TabItem>
        </TabControl>

    </Grid>
</Window>

There should be no code in the MainWindow.xaml.cs file.

Note: you can see that each control in the each tabitem is bound to the exact item in the collection.

MainWindowViewModel.cs
C#
namespace WPFUserControlBinding
{
    public class MainWindowViewModel
    {
        public TabViewModel TabViewModel { get; set; }

        public MainWindowViewModel()
        {
            TabViewModel = new TabViewModel();
        }
    }
}


MyUserControl.xaml
HTML
<UserControl x:Class="WPFUserControlBinding.MyUserControl"
             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:vm="clr-namespace:WPFUserControlBinding"
             mc:Ignorable="d" d:DesignWidth="300" Height="120">
    <Grid d:DataContext="{d:DesignInstance vm:MyUserControlViewModel}">
        <StackPanel >
            <TextBlock x:Name="NameLabel" Text="Name:"/>
            <TextBlock x:Name="Name" Text="{Binding Name}"/>
        </StackPanel>
    </Grid>
</UserControl>


MyUserControlViewModel.cs
C#
namespace WPFUserControlBinding
{
    public class MyUserControlViewModel
    {
        private string _name = string.Empty;

        public string Name
        {
            get { return _name; }
            set
            {
                if (!_name.Equals(value))
                {
                    _name = value;
                }
            }
        }
    }
}


TabViewModel.cs
C#
namespace WPFUserControlBinding
{
    public class TabViewModel
    {
        public MyUserControlViewModel[] TabItems { get; set; }

        public TabViewModel()
        {
            TabItems = new MyUserControlViewModel[]
                {
                    new MyUserControlViewModel() {Name = "Peter"},
                    new MyUserControlViewModel() {Name = "Bob"},
                    new MyUserControlViewModel() {Name = "Tom"}
                };
        }
    }
}


When you run this code, you will see each tab will display the name as from the collection. you can modify the tabViewModel to dynamically load the tab items as per the collection if you want.
 
Share this answer
 
v3
Comments
behnamse 3-Oct-13 2:18am    
Hi, Thank you so much, generaly i got what to do, but i have another question im using Caliburn.Micro so this solution fit for Caliburn.Micro, and there is another thing that in my solution there are 10 projects and there is just 1 project that im working with, so i dont have access to app.xaml, im kind of new in wpf, it would appriciate if you can help me more.Thanks
Jegan Thiyagesan 4-Oct-13 6:34am    
If you do not access to app.xaml it doesn't matter, whoever calls your MonitorProfileOutputViewModel needs to initialize and set the view model before calling them. The app.xaml is an example where the MainWindowViewModel has been called. if you MonitorProfileOutputViewModel has been called in another file, then initialize and set it there.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900