question

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

How to bind from ViewModel to controls in usercontrol

Hi;
I'm using wpf here mvvm. I have some questions.

Right now I'm binding from CategoryViewModel to an ListView - this works perfect. I also set the SelectedCategory when selecting a row in the ListView (that works also - I have checked it with a button on the page).

Now I want when selecting a row in the Listview that row should be viewed in some controls on the page (1 Label, 1 textbox, 2 checkboxes), but I can't figure out how to do this.

Don't pay attention to the ComboBox, that I will ask a question about when those things here works.

Best regards
Simsen :-)

My Model

 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Text;
    
 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"); }
         }
    
         public event PropertyChangedEventHandler PropertyChanged;
    
         private void OnPropertyChanged(string propertyName)
         {
             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
         }
     }
 }

My ViewModel

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using Model.Account;
using DAL.Account;
using System.ComponentModel;
using System.Linq;
using System.Diagnostics;

namespace ViewModel.Account
{
public class CategoryViewModel
{
private Category _selectedCategory;
public MyICommand DeleteCommand { get; set; }

     public Category SelectedCategory
     {
         get
         {
             return _selectedCategory;
         }

         set
         {
             _selectedCategory = value;
             DeleteCommand.RaiseCanExecuteChanged();
         }
     }

     public CategoryViewModel()
     {
         LoadCategories();
         DeleteCommand = new MyICommand(OnDelete, CanDelete);
     }        

     public List<Category> Categories_GetAll { get; set; }
     public List<Category> Categories_GetActive { get; set; }
     public List<Category> Categories_GetInactive { get; set; }

     public void LoadCategories()
     {
         DalCategory dalCategory = new DalCategory();
         var categories = dalCategory.GetCategories();

         if (categories != null)
         {
             //All
             Categories_GetAll = categories;

             //Active
             Categories_GetActive = categories.Where(x => x.CategoryIsObsolete == false).ToList();

             //Inactive
             Categories_GetInactive = categories.Where(x => x.CategoryIsObsolete == true).ToList();
         }
     }


     public void SaveChanges()
     {
         //Her gemmes ændringer
         //CategoryModel mod = new CategoryModel();
         ///Debug.Assert(false, String.Format("{0} was updated", cat.CategoryName));
     }
     #region Delete

     private void OnDelete()
     {
         Category cat = SelectedCategory;
         int id = cat.CategoryId;
         Categories_GetActive.Remove(SelectedCategory);
     }

     private bool CanDelete()
     {
         return SelectedCategory != null;
     }
     #endregion
 }

}


And the UserControl
<UserControl x:Class="Views.Account.AccountObsoleteView"
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:local="clr-namespace:Views.Account"
xmlns:viewModel = "clr-namespace:ViewModel.Account;assembly=ViewModel"
mc:Ignorable="d"
d:DesignHeight="550" d:DesignWidth="1000">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="585" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="989" />
</Grid.ColumnDefinitions>

         <!--<Border BorderThickness="1" BorderBrush="Red" />-->
         <TabControl Grid.Row="0" Grid.Column="0" Style="{StaticResource tabControlSmall}">
             <TabItem Header="Aktive" Style="{StaticResource tabItemSmall}" >
                 <!--Tab aktive/inaktive-->
                 <Grid>
                     <Grid.RowDefinitions>
                         <RowDefinition Height="537" />
                     </Grid.RowDefinitions>
                     <Grid.ColumnDefinitions>
                         <ColumnDefinition Width="475" />
                         <ColumnDefinition Width="490" />
                     </Grid.ColumnDefinitions>
                     <!--<Border BorderThickness="1" BorderBrush="Blue" Grid.ColumnSpan="2" />-->
                     <!--Row 0 Venstre halvdel-->
                     <ListView ItemsSource="{Binding Categories_GetActive}" SelectedItem="{Binding SelectedCategory}" SelectionChanged=""  Grid.Row="0" Grid.Column="0">
                         <ListView.View>
                             <GridView>
                                 <GridViewColumn Header="Id" Width="50" DisplayMemberBinding="{Binding CategoryId}"/>
                                 <GridViewColumn Header="Navn" Width="350"  DisplayMemberBinding="{Binding CategoryName}"/>
                                 <GridViewColumn Header="Global" Width="50"  DisplayMemberBinding="{Binding CategoryIsGlobal}"/>
                                 <GridViewColumn Header="Project" Width="50"  DisplayMemberBinding="{Binding ProjectId}"/>
                             </GridView>
                         </ListView.View>
                     </ListView>
                     <!--Row 0 højre halvdel-->
                     <Grid Grid.Row="0" Grid.Column="1">                    
                         <Grid.RowDefinitions>
                             <RowDefinition Height="35" />
                             <RowDefinition Height="35" />
                             <RowDefinition Height="465" />
                         </Grid.RowDefinitions>
                         <Grid.ColumnDefinitions>
                             <ColumnDefinition Width="489" />
                         </Grid.ColumnDefinitions>
                         <!--Række 0 meddelse-->
                         <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0" Width="480">
                             <Label x:Name="LblMessageCategoryActive" Content="" BorderThickness="1" Height="50" />
                         </StackPanel>                        
                         <!--Række 1 med Ny knappe-->
                         <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Top" Width="100">  
                             <Button x:Name="BtnCategoryActiveNew" Content="Ny" Width="75" Margin="5 0 0 0" />
                         </StackPanel>
                            
                         <!--<Border BorderThickness="1" BorderBrush="Red" Grid.Row="2" Grid.ColumnSpan="4" />-->
                         <Grid Grid.Row="2" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Right" Height="250">
                                
                             <Grid.RowDefinitions>
                                 <RowDefinition Height="5" />
                                 <RowDefinition Height="35" />
                                 <RowDefinition Height="35" />
                                 <RowDefinition Height="35" />
                                 <RowDefinition Height="35" />
                                 <RowDefinition Height="35" />
                                 <RowDefinition Height="45" />
                                 <RowDefinition Height="200" />
                             </Grid.RowDefinitions>
                             <Grid.ColumnDefinitions>
                                 <ColumnDefinition Width="143" />
                                 <ColumnDefinition Width="163" />
                                 <ColumnDefinition Width="183" />
                             </Grid.ColumnDefinitions>
    
                             <!--Row 1-->
                             <Rectangle Grid.Row="1" Grid.Column="1" Fill="#d3d0d0" Grid.ColumnSpan="2" />
                             <Label Content="Id:" Grid.Row="1" Grid.Column="1" HorizontalContentAlignment="Right" />
                             <Label x:Name="LblCategoryActiveId" Margin="0 0 8 0" Content="{Binding Path = CategoryId, Mode = TwoWay}" Grid.Row="1" Grid.Column="2" HorizontalContentAlignment="Left"  />
    
                             <!--Row 2-->
                             <Rectangle Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Fill="#e3e1e1" />
                             <Label Content="Navn:" Grid.Row="2" Grid.Column="1" HorizontalContentAlignment="Right" />
                             <TextBox x:Name="TxtCategoryActiveName" Margin="0 0 8 0" Text="{Binding Path = CategoryName, Mode = TwoWay}" Grid.Row="2" Grid.Column="2" Height="25" />
    
                             <!--Row 3-->
                             <Rectangle Grid.Row="3" Grid.Column="1" Fill="#d3d0d0" Grid.ColumnSpan="2" />
                             <CheckBox x:Name="CbxCategoryActiveGlobal" Content="Global:" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Margin="0 0 168 0" VerticalAlignment="Center" IsChecked="{Binding Path=CategoryIsGlobal, Mode=TwoWay}"  HorizontalContentAlignment="Left" />
    
                             <!--Row 4-->
                             <Rectangle Grid.Row="4" Grid.Column="1" Fill="#e3e1e1" Grid.ColumnSpan="2" />
                             <CheckBox x:Name="CbxCategoryActiveActive" Content="Inaktiv:" Grid.Row="4" Grid.Column="1" Margin="0 0 168 0" VerticalAlignment="Center"  HorizontalContentAlignment="Left" Grid.ColumnSpan="2" IsChecked="{Binding Path=CategoryIsObsolete, Mode=TwoWay}" />
    
                             <!--Row 5 -->
                             <Rectangle Grid.Row="5" Grid.Column="1" Fill="#d3d0d0" Grid.ColumnSpan="2" />
                             <Label Content="Project:" Grid.Row="5" Grid.Column="1" HorizontalContentAlignment="Right" />
                             <ComboBox x:Name="CbxProject" Text="Projekt" Grid.Row="5" Grid.Column="2" HorizontalContentAlignment="Left" VerticalContentAlignment="Center">
                                 <ComboBoxItem>
                                     <TextBlock Text="Test 1" />
                                 </ComboBoxItem>
                                 <ComboBoxItem>
                                     <TextBlock Text="Test 2" />
                                 </ComboBoxItem>
                             </ComboBox>
    
                             <!--Row 6-->
                             <Button x:Name="BtnCategoryActiveSave" Command="{Binding DeleteCommand}" Content="Gem" Width="150" Grid.Column="1" Margin="0 10 0 0" Grid.Row="6" Grid.ColumnSpan="5" HorizontalAlignment="Center" HorizontalContentAlignment="Center" />
    
                         </Grid>
    
                     </Grid>
                 </Grid>
             </TabItem>
             <TabItem Header="Inaktive" Style="{StaticResource tabItemSmall}" >
             </TabItem>
         </TabControl>
     </Grid>
 </UserControl>
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

Anja-7727 avatar image
0 Votes"
Anja-7727 answered

I figured out by myself.

I do off course have to bind the textboxes, labels an so on to the listview - and here to do a path to the selectedValue:

I have changed the code from this:

 <Label x:Name="LblCategoryActiveId" Margin="0 0 8 0" Content="{Binding Path = CategoryId, Mode = TwoWay}" Grid.Row="1" Grid.Column="2" HorizontalContentAlignment="Left"  />

to this

 <Label x:Name="LblCategoryActiveId" Margin="0 0 8 0" Content="{Binding ElementName=LivCategories, Path = SelectedValue.CategoryId, Mode = TwoWay}" Grid.Row="1" Grid.Column="2" HorizontalContentAlignment="Left"  />


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.