question

Anja-7727 avatar image
0 Votes"
Anja-7727 asked Anja-7727 commented

From Model to View with foreign key

Hi all,
I have some understanding issues I hope you can help me with.

Right now I have a table, where I have made a foreign key and then add the foreign keys name whitin the stored procedure. That I know is not the correct way. What I need is a simple example, how to use foreign keys in a mvvm. From the model to the view.

I have 2 models


Category Model - I have comment the one I think not should be here but only in the Project Model

 using System.ComponentModel;
    
 namespace Model.Account
 {
     public class CategoryModel { }
    
     public class Category : INotifyPropertyChanged
     {
         public Category(){}
    
         private int categoryId;
         public int CategoryId
         {
             get { return categoryId; }
             set { categoryId = value; OnPropertyChanged("CategoryId"); }
         }
    
         private string categoryName;
         public string CategoryName
         {
             get { return categoryName; }
             set { categoryName = value; OnPropertyChanged("CategoryName"); }
         }
    
         private bool categoryIsGlobal;
         public bool CategoryIsGlobal
         {
             get { return categoryIsGlobal; }
             set { categoryIsGlobal = value; OnPropertyChanged("CategoryIsGlobal"); }
         }
    
         private bool categoryIsObsolete;
         public bool CategoryIsObsolete
         {
             get { return categoryIsObsolete; }
             set { categoryIsObsolete = value; OnPropertyChanged("CategoryIsObsolete"); }
         }
    
         private int projectId;
         public int ProjectId
         {
             get { return projectId; }
             set { projectId = value; OnPropertyChanged("ProjectId"); }
         }
    
    
         //This one whould not be here that should only be in the ProjectModel
         private string projectName;
         public string ProjectName
         {
             get { return projectName; }
             set { projectName = value; OnPropertyChanged("ProjectName"); }
         }
    
         public event PropertyChangedEventHandler PropertyChanged;
    
         private void OnPropertyChanged(string propertyName)
         {
             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
         }
     }
 }

And the ProjectModel

 using System.ComponentModel;
    
 namespace Model.Projects
 {
     public class ProjectModels { }
     public class Project : INotifyPropertyChanged
     {
         public Project() { }
    
         private int projectId;
    
         public int ProjectId
         {
             get { return projectId; }
             set { projectId = value; OnPropertyChanged("ProjectId"); }
         }
    
         private string projectName;
    
         public string ProjectName
         {
             get { return projectName; }
             set { projectName = value; OnPropertyChanged("ProjectName"); }
         }
    
         private string projectDescription;
    
         public string ProjectDescription
         {
             get { return projectDescription; }
             set { projectDescription = value; OnPropertyChanged("ProjectDescription"); }
         }
    
         private bool projectIsActive;
    
         public bool ProjectIsActive
         {
             get { return projectIsActive; }
             set { projectIsActive = value; OnPropertyChanged("ProjectIsActive"); }
         }
    
         public event PropertyChangedEventHandler PropertyChanged;
    
         private void OnPropertyChanged(string propertyName)
         {
             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
         }
     }
 }

Now I need som help to find an example where I can see what to do in the ViewModel and how to do in the View where I have ListView with the Category and the ProjectName. like this CategoryId, CategoryName, ProjectName

The examples I have seen is without a forereign key, so I have no clue to make a list where I add two models into one view? (yes I know I can do it in the stored procedure) but doesn't look right in the model.

Best regards
Simsen :-)

windows-wpf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered Anja-7727 commented

Hi Anja,
you can use converter to get ProjectName from ProjectId like in following demo:

 <Window x:Class="WpfApp1.Window050"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:WpfApp050"
         mc:Ignorable="d"
         Title="Anja-7727 210430" Height="450" Width="800">
   <Window.Resources>
     <local:ViewModel x:Key="vm"/>
     <local:ProjectConverter x:Key="conv"/>
   </Window.Resources>
   <Grid DataContext="{StaticResource vm}">
     <ListView ItemsSource="{Binding ViewCategory}">
       <ListView.View>
         <GridView>
           <GridViewColumn Header="ID" DisplayMemberBinding="{Binding CategoryId}" Width="50"/>
           <GridViewColumn Header="CategoryName" DisplayMemberBinding="{Binding CategoryName}" Width="150"/>
           <GridViewColumn Header="ProjectName" 
                           DisplayMemberBinding="{Binding ProjectId,
             Converter={StaticResource conv}, ConverterParameter={StaticResource vm}}" Width="150"/>
         </GridView>
       </ListView.View>
     </ListView>
   </Grid>
 </Window>

And classes:

 using System;
 using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Globalization;
 using System.Linq;
 using System.Windows;
 using System.Windows.Data;
    
 namespace WpfApp050
 {
   public class ViewModel
   {
     public ViewModel() => LoadData();
    
     private CollectionViewSource cvsCategory = new CollectionViewSource();
     public ICollectionView ViewCategory { get => cvsCategory.View; }
    
     public ObservableCollection<Project> ColProject = new ObservableCollection<Project>();
    
     private void LoadData()
     {
       // generate demo data
       for (int i = 1; i < 10; i++)
         ColProject.Add(new Project() { ProjectId = i, ProjectName = $"ProjectName {i}" });
       Random rnd = new Random();
       ObservableCollection<Category> colCategory = new ObservableCollection<Category>();
       for (int i = 1; i < 100; i++)
         colCategory.Add(new Category() { CategoryId = i, CategoryName = $"CategoryName {i}", ProjectId = rnd.Next(1, ColProject.Count) });
       cvsCategory.Source = colCategory;
     }
   }
    
   public class ProjectConverter : IValueConverter
   {
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
     {
       int id = (int)value;
       ViewModel vm = parameter as ViewModel;
       if (vm == null) return null;
       var pr = vm.ColProject.FirstOrDefault<Project>((p) => p.ProjectId == id);
       return pr.ProjectName;
     }
    
     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
     {
       throw new NotImplementedException();
     }
   }
    
   public class CategoryModel { }
    
   public class Category : INotifyPropertyChanged
   {
     public Category() { }
    
     private int categoryId;
     public int CategoryId
     {
       get { return categoryId; }
       set { categoryId = value; OnPropertyChanged("CategoryId"); }
     }
    
     private string categoryName;
     public string CategoryName
     {
       get { return categoryName; }
       set { categoryName = value; OnPropertyChanged("CategoryName"); }
     }
    
     private bool categoryIsGlobal;
     public bool CategoryIsGlobal
     {
       get { return categoryIsGlobal; }
       set { categoryIsGlobal = value; OnPropertyChanged("CategoryIsGlobal"); }
     }
    
     private bool categoryIsObsolete;
     public bool CategoryIsObsolete
     {
       get { return categoryIsObsolete; }
       set { categoryIsObsolete = value; OnPropertyChanged("CategoryIsObsolete"); }
     }
    
     private int projectId;
     public int ProjectId
     {
       get { return projectId; }
       set { projectId = value; OnPropertyChanged("ProjectId"); }
     }
    
     public event PropertyChangedEventHandler PropertyChanged;
     private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   }
    
   public class ProjectModels { }
   public class Project : INotifyPropertyChanged
   {
     public Project() { }
    
     private int projectId;
    
     public int ProjectId
     {
       get { return projectId; }
       set { projectId = value; OnPropertyChanged("ProjectId"); }
     }
    
     private string projectName;
    
     public string ProjectName
     {
       get { return projectName; }
       set { projectName = value; OnPropertyChanged("ProjectName"); }
     }
    
     private string projectDescription;
    
     public string ProjectDescription
     {
       get { return projectDescription; }
       set { projectDescription = value; OnPropertyChanged("ProjectDescription"); }
     }
    
     private bool projectIsActive;
    
     public bool ProjectIsActive
     {
       get { return projectIsActive; }
       set { projectIsActive = value; OnPropertyChanged("ProjectIsActive"); }
     }
    
     public event PropertyChangedEventHandler PropertyChanged;
     private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   }
 }

Result:

93132-x.png



x.png (51.5 KiB)
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you very much again I will do that tomorrow :-)

0 Votes 0 ·