I have one action in my view model to add record in to entity frame work.I have one action to display the records in the view like this :
private void FillProspects()
{
var q = (from a in ctx2.Prospects// 'ctx' is the object of entity
select a).ToList();
this.Prospects = q; // 'Porspects' is a collection of entity class this I have bound with my List view in my view
}
This will be called in construction of my view model.as a result the list view in my view will be showing the records .
I have one add record action in my view model..I have created properties in my view model corresponding to properties generated in the entity class for example:
private String _FirstName;
public String FirstName
{
get
{
return _FirstName;
}
set
{
_FirstName = value;
}
}
And my add record action in the view model is :
public void Add1()
{
newprospect = new Prospect();
newprospect.ID = Guid.NewGuid();
newprospect.FirstName = FirstName;
newprospect.LastName = LastName;
newprospect.Address = Address;
newprospect.State = State;
newprospect.City = City;
newprospect.ZIP = ZIP;
prospect = newprospect;
ctx2.AddToProspects(prospect);
FillProspects();
//RaisePropertyChanged("Prospects");
}
I have inherited the : INotifyPropertyChanged and imported it's
using System.Windows.Input;
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private void RaisePropertyChanged(string property) { PropertyChanged(this, new PropertyChangedEventArgs(property)); }
But my notification is not refreshing my view Listview records after adding record .so I just call the fill records method 'FillProspects' in the addrecord action..Is this right way of doing MVVM .Why my Listview is not getting refreshed after add record action where I am missing?I have tried with
RaisePropertyChanged("Prospects");in the Add record action...but it is not refreshing .So I just called fill method action again
My complete view model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Input;
using System.Collections.ObjectModel;
namespace Wpfentity3
{
public class frmProspects_VM : INotifyPropertyChanged
{
TestsEntities ctx2 = new TestsEntities();
public ObservableCollection<Prospect> prospects { get; set; }
//This is the collection where records - er, entities - returned by a query are stored;
//Prospect is the generated class that defines a record - er,
//an entity as well as the query for that table.
private CommandMap _Commands;
public CommandMap Commands { get { return _Commands; } }
Prospect newprospect;
//This holds a new prospect that is created and then added to the prospects collection
private Prospect _prospect;
public Prospect prospect {
get
{
return _prospect;
}
set
{
_prospect = value;
RaisePropertyChanged("prospect");
}
}
//prospect is the object that holds the current record from the Prospects table.
//MainWindow controls are bound to this object
public frmProspects_VM()
{
//FillProspects();
ctx2 = new TestsEntities();
//This instantiates the EntityManager class ;
prospects = new ObservableCollection<Prospect>();
//This instantiates the prospects collection of Prospect records - er, entities;
_Commands = new CommandMap();
_Commands.AddCommand("Add", x => Add1());
}
private ObservableCollection<Prospect> _prospects;
public ObservableCollection<Prospect> Prospects
{
get
{
return _prospects;
}
set
{
_prospects = value;
RaisePropertyChanged("Prospects");
}
}
private String _FirstName;
public String FirstName
{
get
{
return _FirstName;
}
set
{
_FirstName = value;
}
}
private String _LastName;
public String LastName
{
get
{
return _LastName;
}
set
{
_LastName = value;
}
}
private String _Address;
public String Address
{
get
{
return _Address;
}
set
{
_Address = value;
}
}
private String _State;
public String State
{
get
{
return _State;
}
set
{
_State = value;
}
}
private String _City;
public String City
{
get
{
return _City;
}
set
{
_City = value;
}
}
private String _ZIP;
public String ZIP
{
get
{
return _ZIP;
}
set
{
_ZIP = value;
}
}
public void Add1()
{
newprospect = new Prospect();
newprospect.ID = Guid.NewGuid();
newprospect.FirstName = FirstName;
newprospect.LastName = LastName;
newprospect.Address = Address;
newprospect.State = State;
newprospect.City = City;
newprospect.ZIP = ZIP;
prospect = newprospect;
ctx2.AddToProspects(prospect);
Prospects.Add(newprospect);
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private void RaisePropertyChanged(string property) { PropertyChanged(this, new PropertyChangedEventArgs(property)); }
}
}
My view xamal:
<Window x:Class="Wpfentity3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStartupLocation="CenterScreen"
Title="Prospects"
Height="482" Width="500" MaxWidth="500" MaxHeight="600"
xmlns:cusns="clr-namespace:Wpfentity3">
<StackPanel Height="290" VerticalAlignment="Top">
<StackPanel Orientation="Horizontal" >
<Label
Content="Prospects"
BorderBrush="Blue" BorderThickness="1"
HorizontalAlignment="Left" VerticalAlignment="Top"
FontSize="24" FontFamily="Comic Sans MS"
Padding="13,3,13,9" Margin="5"
Foreground="Purple" Background="LemonChiffon" />
<Label
Content="{Binding Path=label}" Foreground="Red" FontSize="14"
HorizontalAlignment="Right" VerticalAlignment="Center"
Height="auto" Margin="180,0,10,0" />
</StackPanel>
<Grid
HorizontalAlignment="Left" VerticalAlignment="Top"
Height="120" Width="475" >
<Grid.RowDefinitions>
<RowDefinition Height="25*" />
<RowDefinition Height="25*" />
<RowDefinition Height="25*" />
<RowDefinition Height="25*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90*" />
<ColumnDefinition Width="135*" />
<ColumnDefinition Width="45*" />
<ColumnDefinition Width="32*" />
<ColumnDefinition Width="57*" />
<ColumnDefinition Width="118*" />
</Grid.ColumnDefinitions>
<Label
Content="First name"
Grid.Row="0" Grid.Column="0" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtFirstName"
Grid.Column="1"
HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding Path=FirstName}"
Width="130" />
<Label
Content="Last name"
Grid.Row="1" Grid.Column="0" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtLastName"
Grid.Row="1" Grid.Column="1"
HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding LastName}"
Width="130" />
<Label
Content="Address"
Grid.Row="2" Grid.Column="0" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtAddress"
Grid.Row="2" Grid.Column="1"
HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding Address}"
Width="300" Grid.ColumnSpan="5" />
<Label
Content="City"
Grid.Row="3" Grid.Column="0" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtCity"
Grid.Row="3" Grid.Column="1"
HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding City}"
Width="130" />
<Label
Content="State"
Grid.Row="3" Grid.Column="2" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtState"
Grid.Row="3" Grid.Column="3" Width="30" MaxLength="2" CharacterCasing="Upper" Text="{Binding State}"
HorizontalAlignment="Left" VerticalAlignment="Center" />
<Label
Content="ZIP code"
Grid.Row="3" Grid.Column="4" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtZIP"
Grid.Row="3" Grid.Column="5" MaxLength="10"
HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding ZIP}"
Width="90" />
</Grid>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Button Name="btnFind"
Content="_Find"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnAdd"
Content="_Add" Command="{Binding Commands.Add}"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnEdit"
Content="_Edit"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnDelete"
Content="_Delete"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnSave"
Content="_Save"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnCancel"
Content="_Cancel"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnClose"
Content="Cl_ose"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0"
/>
</StackPanel>
<StackPanel Height="34" Margin="10">
<Grid Margin="10">
<ListView Name="lvprospects" ItemsSource="{Binding Prospects}" Margin="0,0,0,-200">
<ListView.View>
<GridView>
<GridViewColumn Header="FirstName" Width="120" DisplayMemberBinding="{Binding FirstName}" />
<GridViewColumn Header="LastName" Width="50" DisplayMemberBinding="{Binding LastName}" />
<GridViewColumn Header="Address" Width="50" DisplayMemberBinding="{Binding Address}" />
<GridViewColumn Header="City" Width="50" DisplayMemberBinding="{Binding City}" />
<GridViewColumn Header="State" Width="50" DisplayMemberBinding="{Binding State}" />
<GridViewColumn Header="ZIP" Width="50" DisplayMemberBinding="{Binding ZIP}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</StackPanel>
</StackPanel>
Change the type of the Prospects property from List<Prospect> to ObservableCollection<Prospect>:
private ObservableCollection<Prospect> _prospects = new ObservableCollection<Prospect>();
public ObservableCollection<Prospect> Prospects
{
get
{
return _prospects;
}
set
{
_prospects = value;
RaisePropertyChanged("Prospects");
}
}
And add the new Prospect object to this collection as well in your Add1 method:
public void Add1()
{
newprospect = new Prospect();
newprospect.ID = Guid.NewGuid();
newprospect.FirstName = FirstName;
newprospect.LastName = LastName;
newprospect.Address = Address;
newprospect.State = State;
newprospect.City = City;
newprospect.ZIP = ZIP;
prospect = newprospect;
ctx2.AddToProspects(prospect);
Prospects.Add(newprospect);
}
Just adding it to the DbContext doesn't affect the ListView.
It is fine to add the new item to the DB and then retrieve again the collection with the same refresh method FillProspects:
what you're doing is basically correct.
If you're going to bind a view to a collection in your ViewModel, I suggest using an ObservableCollection.
The ObservableCollection implements INotifyCollectionChanged, it notifies the view when elements are added or removed.
With this you should not need your "FillProspects" method and your "RaisePropertyChanged("Prospects")".
If you want more information I suggest posting how you bind in your XAML and also how you construct your "Prospects" object (we don't even know what type it is, I just assume it isn't an ObservableCollection).
EDIT :
you bind your ListView to "Prospects", but in your ViewModel, I see that "Prospects" is of type "List", it needs to be "ObservableCollection". I see that you have an ObservableCollection named "prospects", but you don't use it anywhere. Could this be the issue ?
Related
I have a datagrid which holds the User information. Now once, I click on the selected row, I want to display the user information such as their roles and allow the user to edit the user roles by clicking on the combobox. Under my data template I have the combobox in my xaml. Since using the datatemplate, the combobox name couldnt be found, I am using the following method below to get the children from the grid.
Here is the code to get the children element:
private List<FrameworkElement> GetChildren(DependencyObject parent)
{
List<FrameworkElement> controls = new List<FrameworkElement>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); ++i)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is FrameworkElement)
{
controls.Add(child as FrameworkElement);
}
controls.AddRange(GetChildren(child));
}
return controls;
}
I created the selection changed event for the datagrid:
private void userDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var userRolesList = new User().getUserRoles();
ComboBox cbUserRole = (ComboBox)GetChildren(userDataGrid).First(x => x.Name == "cbUserRole");
cbUserRole.ItemsSource = userRolesList;
}
Now when I run this code, I am being shown error message
Sequence contains no matching element
The same method I use for my textboxes, I am able to display the values and edit the values too. But for my combobox its not working the way it supposed to. Can someone please help me on this. Thanks.
This is my xaml code:
<DataGrid AutoGenerateColumns="False" Grid.Row="2" Grid.ColumnSpan="4" Grid.RowSpan="3" x:Name="userDataGrid" Margin="70,0.2,70,0" ItemsSource="{Binding}" SelectionChanged="userDataGrid_SelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding UserId}"/>
<DataGridTextColumn Header="Username" Binding="{Binding UserName}"/>
<DataGridTextColumn Header="Email" Binding="{Binding UserEmail}"/>
<DataGridTextColumn Header="User Role" Binding="{Binding UserRole}"/>
<DataGridTextColumn Header="Created Date" Binding="{Binding UserCreatedDate}"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border BorderThickness="0" Background="BlanchedAlmond" Padding="10">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="User ID: " VerticalAlignment="Center" />
<TextBlock x:Name="txtBlockId" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserId, Mode=TwoWay}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="First Name: " VerticalAlignment="Center" />
<TextBox x:Name="txtFirstName" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserFirstName, Mode=TwoWay}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="Last Name: " VerticalAlignment="Center" />
<TextBox x:Name="txtLastName" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserLastName}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="User Role: " VerticalAlignment="Center" />
<ComboBox x:Name="cbUserRole" FlowDirection="LeftToRight" FontSize="16" Foreground="MidnightBlue" HorizontalAlignment="Stretch" VerticalAlignment="Center" SelectionChanged="cbUserRole_Click"/>
</StackPanel>
<StackPanel>
<Button x:Name="btnUpdate" Content="Update" VerticalAlignment="Center" HorizontalAlignment="Right" Click="btnUpdate_Click"/>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
Thanks
I've been seeing you asking around how to work with this, let me show you one way, hope this helps, but I recommend you read about MVVM patterns and frameworks like MVVMLight for WPF.
Well, for this, first you need to install Install-Package MvvmLight -Version 5.4.1
Then you may need to fix one reference issue, in the ViewModelLocator, remove all the usings and replace with:
using GalaSoft.MvvmLight.Ioc;
using CommonServiceLocator;
Now, your MainWindowView.xaml, it should like:
<Window x:Class="WpfApp2.MainWindow"
x:Name="root"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:WpfApp2.ViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<vm:MainViewModel x:Name="Model"/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DataGrid AutoGenerateColumns="False" x:Name="userDataGrid" Margin="70,0.2,70,0" ItemsSource="{Binding Users}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding UserId}"/>
<DataGridTextColumn Header="Username" Binding="{Binding UserName}"/>
<DataGridTextColumn Header="Email" Binding="{Binding UserEmail}"/>
<DataGridTextColumn Header="User Role" Binding="{Binding UserRole}"/>
<DataGridTextColumn Header="Created Date" Binding="{Binding UserCreatedDate}"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border BorderThickness="0" Background="BlanchedAlmond" Padding="10">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="User ID: " VerticalAlignment="Center" />
<TextBlock x:Name="txtBlockId" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserId, Mode=TwoWay}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="First Name: " VerticalAlignment="Center" />
<TextBox x:Name="txtFirstName" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserFirstName, Mode=TwoWay}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="Last Name: " VerticalAlignment="Center" />
<TextBox x:Name="txtLastName" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserLastName}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="User Role: " VerticalAlignment="Center" />
<ComboBox ItemsSource="{Binding Path=DataContext.UserRoles, ElementName=root}" SelectionChanged='CbUserRole_OnSelectionChanged' SelectedItem="{Binding UserRole}" x:Name="cbUserRole" FlowDirection="LeftToRight" FontSize="16" Foreground="MidnightBlue" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
</StackPanel>
<StackPanel>
<Button x:Name="btnUpdate" Content="Update" VerticalAlignment="Center" HorizontalAlignment="Right" Command="{Binding UpdateCommand, ElementName=Model}" CommandParameter="{Binding}" />
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Grid>
</Window>
Then in your code-behind, there's a little event handling that needs to be done, when changing the roles,
using System.Windows;
using System.Windows.Controls;
using WpfApp2.ViewModel;
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public MainViewModel ViewModel => (MainViewModel) DataContext;
private void CbUserRole_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox cb = (ComboBox)sender;
if (cb != null)
{
ViewModel.SelectedUserRole = (UserRole)cb.SelectedItem;
}
}
}
}
Then you should create a ViewModel like so (ViewModel -> MainViewModel.cs):
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using GalaSoft.MvvmLight.Command;
using WpfApp2.Data;
namespace WpfApp2.ViewModel
{
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
PopulateUserTestData();
UpdateCommand = new RelayCommand<User>(UpdateUser);
}
private ObservableCollection<User> _users;
public ObservableCollection<User> Users
{
get => _users;
set
{
if (_users != value)
{
_users = value;
NotifyPropertyChanged();
}
}
}
private UserRole _userRole;
public UserRole SelectedUserRole
{
get => _userRole;
set
{
if (_userRole != value)
{
_userRole = value;
NotifyPropertyChanged();
}
}
}
public RelayCommand<User> UpdateCommand { get; }
public IEnumerable<UserRole> UserRoles => Enum.GetValues(typeof(UserRole)).Cast<UserRole>();
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void UpdateUser(User user)
{
Users.Single(u => u.UserId == user.UserId).UserRole = SelectedUserRole;
// Do updates on your context (or in-memory).
PrintUsersOnDebug();
}
#region Test data and diagnostics support
private void PrintUsersOnDebug()
{
foreach (User user in Users)
{
Debug.WriteLine("Username: " + user.UserName + " Role: " + user.UserRole);
}
}
private void PopulateUserTestData()
{
Users = new ObservableCollection<User>
{
new User
{
UserId = 1,
UserCreatedDate = DateTime.Now,
UserEmail = "johndoe1#email.com",
UserFirstName = "John",
UserLastName = "Doe",
UserName = "johnd",
UserRole = UserRole.Administrator
},
new User
{
UserId = 2,
UserCreatedDate = DateTime.Now,
UserEmail = "billgordon#email.com",
UserFirstName = "Bill",
UserLastName = "Gordon",
UserName = "billg",
UserRole = UserRole.SuperUser
}
};
PrintUsersOnDebug();
}
#endregion
}
}
Other related classes:
Data->User.cs
using System;
namespace WpfApp2.Data
{
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
public string UserEmail { get; set; }
public UserRole UserRole { get; set; }
public DateTime UserCreatedDate { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
}
}
UserRole.cs
namespace WpfApp2
{
public enum UserRole
{
Administrator,
User,
SuperUser
}
}
Now since I just designed this test app to view the changing data in this case roles, I designed this to be just viewable on output window. As you change the roles and click the update button, inspect the output window.
If you simply want to populate the ComboBox in the RowDetailsTemplate, you could handle its Loaded event:
private void cbUserRole_Loaded(object sender, RoutedEventArgs e)
{
ComboBox cbUserRole = (ComboBox)sender;
if (cbUserRole.ItemsSource == null)
cbUserRole.ItemsSource = new User().getUserRoles();
}
XAML:
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="User Role: " VerticalAlignment="Center" />
<ComboBox x:Name="cbUserRole"
Loaded="cbUserRole_Loaded"
FlowDirection="LeftToRight" FontSize="16" Foreground="MidnightBlue" HorizontalAlignment="Stretch"
VerticalAlignment="Center"
SelectionChanged="cbUserRole_Click"/>
</StackPanel>
I'm creating CRUD application in C# with Caliburn.Micro and I have some Master Detail View that looks like that:
What i want to achieve is, when i make some changes(for example i change capacity from 47 to 50), and then select the other place, let's say Place 4 and select Place 5 again my capacity will be 47, not 50 like it is now.
I was thinking about OneTime binding, and manually firing binding to the viewmodel then, but viewModel should not have been aware of the view, so that seems like a bad idea. My code below.
XAML:
<DataGrid x:Name="Places"
Grid.Column="0" Grid.Row="0" Grid.RowSpan="2"
Width="290"
HorizontalAlignment="Left"
CanUserReorderColumns="False" CanUserResizeColumns="False" IsReadOnly="True"
AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="False" SelectionMode="Single">
<DataGrid.Columns>
<DataGridTextColumn Header="Place" Binding="{Binding Name, Mode=OneTime}" MinWidth="150"
Width="SizeToCells" />
</DataGrid.Columns>
</DataGrid>
<Grid Grid.Column="0" Grid.Row="2"
Width="290" Height="210"
HorizontalAlignment="Left" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110" />
<ColumnDefinition Width="180" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="60" />
<RowDefinition Height="30" />
<RowDefinition Height="60" />
</Grid.RowDefinitions>
<Label Content="ID"
Grid.Column="0" Grid.Row="0" VerticalAlignment="Top" />
<Label Content="Place*"
Grid.Column="0" Grid.Row="1" VerticalAlignment="Top" />
<Label Content="Address*"
Grid.Column="0" Grid.Row="2" VerticalAlignment="Top" />
<Label Content="Capacity*"
Grid.Column="0" Grid.Row="3" VerticalAlignment="Top" />
<Label Content="Comments"
Grid.Column="0" Grid.Row="4" VerticalAlignment="Top" />
<TextBox x:Name="SelectedPlace_Id"
Grid.Column="1" Grid.Row="0" VerticalAlignment="Top"
IsEnabled="False" />
<TextBox x:Name="SelectedPlace_Name"
Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" />
<TextBox x:Name="SelectedPlace_Address"
Grid.Column="1" Grid.Row="2"
Height="55" VerticalAlignment="Top"
TextWrapping="Wrap" />
<TextBox x:Name="SelectedPlace_Capacity"
Grid.Column="1" Grid.Row="3" VerticalAlignment="Top" />
<TextBox x:Name="SelectedPlace_Comments"
Grid.Column="1" Grid.Row="4" Height="55"
VerticalAlignment="Top"
TextWrapping="Wrap" />
</Grid>
<Button x:Name="DeletePlace" Content="Delete"
Grid.Column="0" Grid.Row="3"
Width="100" Height="30" Margin="0 0 110 0"
HorizontalAlignment="Right" VerticalAlignment="Top" />
<Button x:Name="SavePlace" Content="Save"
Grid.Column="0" Grid.Row="3"
Width="100" Height="30" Margin="0 0 5 0"
HorizontalAlignment="Right" VerticalAlignment="Top" />
ViewModel:
class PlacesTabViewModel : TabViewModel
{
#region Fields
private BindableCollection<Place> _places;
private Place _selectedPlace;
#endregion
#region Methods
public PlacesTabViewModel()
{
using (var ctx = new DbCtx(App.DatabasePath))
{
_places = new BindableCollection<Place>(ctx.Places.OrderBy(p => p.Name));
}
}
public override string ToString()
{
return "Places";
}
#endregion
#region Events
public bool CanDeletePlace => _selectedPlace != null;
public bool CanSavePlace => (_selectedPlace != null) && _selectedPlace.IsValid();
public void DeletePlace()
{
using (var ctx = new DbCtx(App.DatabasePath))
{
try
{
ctx.Entry(SelectedPlace).State = EntityState.Deleted;
ctx.SaveChanges();
}
catch (DbUpdateException)
{
//TODO: Error
return;
}
Places.Remove(SelectedPlace);
NotifyOfPropertyChange(nameof(Places));
NotifyOfPropertyChange(() => CanDeletePlace);
NotifyOfPropertyChange(() => CanSavePlace);
}
}
public void SavePlace()
{
using (var ctx = new DbCtx(App.DatabasePath))
{
try
{
ctx.Places.Attach(_selectedPlace);
ctx.Entry(_selectedPlace).State = EntityState.Modified;
ctx.SaveChanges();
}
catch
{
//TODO: Error
}
NotifyOfPropertyChange(nameof(Places));
}
}
#endregion
#region Properties
public BindableCollection<Place> Places
{
get { return _places; }
set
{
if (value != _places)
{
_places = value;
NotifyOfPropertyChange(nameof(Places));
}
}
}
public Place SelectedPlace
{
get { return _selectedPlace; }
set
{
if (value != _selectedPlace)
{
_selectedPlace = value;
if (_selectedPlace != null)
{
_selectedPlace.PropertyChanged += (sender, args) =>
{
NotifyOfPropertyChange(() => CanSavePlace);
};
}
NotifyOfPropertyChange(nameof(SelectedPlace));
NotifyOfPropertyChange(() => CanDeletePlace);
NotifyOfPropertyChange(() => CanSavePlace);
}
}
}
#endregion
}
ViewModel for the MainWindow
class MainWindowViewModel : PropertyChangedBase
{
#region Fields
private BindableCollection<TabViewModel> _tabs = new BindableCollection<TabViewModel>();
#endregion
public MainWindowViewModel()
{
_tabs.Add(new PlacesTabViewModel());
}
#region Properties
public BindableCollection<TabViewModel> Tabs
{
get { return _tabs; }
set
{
if (value != _tabs)
{
_tabs = value;
NotifyOfPropertyChange(nameof(Tabs));
}
}
}
#endregion
}
WPF doesn't know Normal properties. You either have to make it a dependency property, or in your case, your VM has to implement INotifyPropertyChanged. when the value changes it will automatically updated.
May be you didn't applied INotifyPropertyChanged property for SelectedPlace_Capacity.
I think that this is the issue.
Hi I am using WPF and MVVM, There is "Edit/Update" Panel in my application it updates selected data in Grid. It is working fine. I want to add one button "Close Button" and "one check to see whether user has selected item or not. If he doesn't select any item and click on "Edit Button" It will show a MessageBox to user to select an item to edit. Thing i am not getting clear is that how to pass "Selected item to do these two things" and to check before closing panel that is there any text in textbox fields or not.
User View Model Code:
public class UserViewModel
{
private IList<User> _UsersList;
public UserViewModel()
{
_UsersList = new List<User>
{
new User { UserId = 1, FirstName = "Raj", LastName = "Beniwal", City = "Delhi", State = "DEL", Country = "INDIA" },
new User { UserId = 2, FirstName = "Mark", LastName = "henry", City = "New York", State = "NY", Country = "USA" },
new User { UserId = 3, FirstName = "Mahesh", LastName = "Chand", City = "Philadelphia", State = "PHL", Country = "USA" },
new User { UserId = 4, FirstName = "Vikash", LastName = "Nanda", City = "Noida", State = "UP", Country = "INDIA" },
new User { UserId = 5, FirstName = "Harsh", LastName = "Kumar", City = "Ghaziabad", State = "UP", Country = "INDIA" },
new User { UserId = 6, FirstName = "Reetesh", LastName = "Tomar", City = "Mumbai", State = "MP", Country = "INDIA" },
new User { UserId = 7, FirstName = "Deven", LastName = "Verma", City = "Palwal", State = "HP", Country = "INDIA" },
new User { UserId = 8, FirstName = "Ravi", LastName = "Taneja", City = "Delhi", State = "DEL", Country = "INDIA" }
};
}
public IList<User> Users
{
get { return _UsersList; }
set { _UsersList = value; }
}
private ICommand mUpdater;
public ICommand UpdateCommand
{
get
{
if (mUpdater == null)
{
mUpdater = new Updater();
}
return mUpdater;
}
set
{
mUpdater = value;
}
}
private class Updater : ICommand
{
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
}
#endregion
}
}
User View Window.Xaml
Panel1
<dxdo:LayoutPanel Caption="Panel1" x:Name="Panel1">
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Name="UserGrid" Grid.Row="1" Margin="4,178,12,13" ItemsSource="{Binding Users}">
<ListView.View>
<GridView x:Name="grdTest">
<GridViewColumn Header="UserId" DisplayMemberBinding="{Binding UserId}" Width="50" />
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="80" />
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="100" />
<GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" Width="80" />
<GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" Width="80" />
<GridViewColumn Header="Country" DisplayMemberBinding="{Binding Country}" Width="100" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</dxdo:LayoutPanel>
<dxdo:LayoutPanel x:Name="Panel3">
<Grid>
<StackPanel>
<Button Content="Edit" Height="23" HorizontalAlignment="Left" VerticalAlignment="Top" Width="141" Click="Button_Click_1" />
</StackPanel>
</Grid>
</dxdo:LayoutPanel>
Panel2:
<dxdo:LayoutPanel Caption="Panel2" x:Name="Panel2">
<Grid>
<StackPanel Margin="0,0,0,10">
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtUserId" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid, Path=SelectedItem.UserId}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtFirstName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid, Path=SelectedItem.FirstName}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,62,0,0" Name="txtLastName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid, Path=SelectedItem.LastName}" />
<Label Content="UserId" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,274" Name="label1" />
<Label Content="Last Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,60,0,0" Name="label2" VerticalAlignment="Top" />
<Label Content="First Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,35,0,0" Name="label3" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,143,0,0" x:Name="txtCity" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.City, ElementName=UserGrid}" />
<Label Content="Country" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,141,0,0" x:Name="label2_Copy" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,88,0,0" x:Name="txtCountry" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.Country, ElementName=UserGrid}" />
<Label Content="City" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,86,0,0" x:Name="label2_Copy1" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,115,0,0" x:Name="txtSTate" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.State, ElementName=UserGrid}" />
<Label Content="State" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,113,0,0" x:Name="label2_Copy2" VerticalAlignment="Top" />
</Grid>
<Button Content="Update" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="310,40,0,0" Name="btnUpdate" VerticalAlignment="Top" Width="141" Command="{Binding Path=UpdateCommad}" />
<Button Content="Close" Grid.Row="1" Height="23" HorizontalAlignment="Right" VerticalAlignment="Top" Width="141" Click="Button_Click_2" />
<TextBox Width="166" Background="White" Height="33" HorizontalAlignment="Right" VerticalAlignment="Bottom" Text="{Binding Path=SelectedCustomer.LastName,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</Grid>
</dxdo:LayoutPanel>
(If my question is not clear to you plesae ask me. Thank you)
Create a Property in the ViewModel for saving the selected User:
public User SelectedUser { get; set; }
Bind SelectedItem of the ListView to this Property:
<ListView Name="UserGrid" ItemsSource="{Binding Users}" SelectedItem="{Binding SelectedUser}">
Now you just have to check if the SelectedUser property is null.
how to pass "Selected item to do these two things"
This usually can be achieved with SelectedSomething property in your view model. This property should be bound to SelectedItem of control.
and to check before closing panel that is there any text in textbox fields or not
This is called "validation". WPF supports validation in several ways, one of them is implementing IDataErrorInfo in your view model. I'd recommend this way, because it is a de facto standard for .NET (it is used in WinForms and ASP .NET as well).
one check to see whether user has selected item or not. If he doesn't select any item and click on "Edit Button" It will show a MessageBox to user to select an item to edit
Again, usually, this being solved with ICommand instance, bound to the button. If ICommand.CanExecute returns false, bound button becomes disabled.
For example, you should check for validation errors in CanExecute for command, bound to Close button, and return false, if there are any errors. Or you should check SelectedSomething property in CanExecute for command, bound to Edit button, and return false, if SelectedSomething == null.
In MVVM world thing becomes easier, if you use RelayCommand/DelegateCommand as the default ICommand implementation.
Update.
A code sample for commands.
View model:
public class UserViewModel
{
public UserViewModel()
{
EditCommand = new RelayCommand(EditSelectedUser, () => SelectedUser != null);
}
private void EditSelectedUser()
{
// some edit code here
}
public User SelectedUser { get; set; }
public ICommand EditCommand { get; private set; }
}
XAML:
<Button Content="Edit" Command="{Binding EditCommand}"/>
I have made a wpf application for implementing the MVVM architecture. I can see the forma but the data is not loaded in the form please help is needed. I am using Visual studio 2012.
Below is the code:
Model:- User.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace TestApplication.Model
{
public class User : INotifyPropertyChanged
{
private int userId;
private string firstName;
private string lastName;
private string city;
private string state;
private string country;
public int UserId
{
get
{
return userId;
}
set
{
userId = value;
OnPropertyChanged("UserId");
}
}
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
OnPropertyChanged("FirstName");
}
}
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
OnPropertyChanged("LastName");
}
}
public string City
{
get
{
return city;
}
set
{
city = value;
OnPropertyChanged("City");
}
}
public string State
{
get
{
return state;
}
set
{
state = value;
OnPropertyChanged("State");
}
}
public string Country
{
get
{
return country;
}
set
{
country = value;
OnPropertyChanged("Country");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
View :- MainPage.xml
<Window x:Class="TestApplication.View.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestApplication" Height="485" Width="525">
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Name="UserGrid" Grid.Row="1" Margin="4,178,12,13" ItemsSource="{Binding Users}" >
<ListView.View>
<GridView x:Name="grdTest">
<GridViewColumn Header="UserId" DisplayMemberBinding="{Binding UserId}" Width="50"/>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="80" />
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="100" />
<GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" Width="80" />
<GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" Width="80" />
<GridViewColumn Header="Country" DisplayMemberBinding="{Binding Country}" Width="100" />
</GridView>
</ListView.View>
</ListView>
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtUserId" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.UserId}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtFirstName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.FirstName}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,62,0,0" Name="txtLastName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.LastName}" />
<Label Content="UserId" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,274" Name="label1" />
<Label Content="Last Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,60,0,0" Name="label2" VerticalAlignment="Top" />
<Label Content="First Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,35,0,0" Name="label3" VerticalAlignment="Top" />
<Button Content="Update" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="310,40,0,0" Name="btnUpdate"
VerticalAlignment="Top" Width="141"
Command="{Binding Path=UpdateCommad}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,143,0,0" x:Name="txtCity" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.City, ElementName=UserGrid}" />
<Label Content="Country" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,141,0,0" x:Name="label2_Copy" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,88,0,0" x:Name="txtCountry" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.Country, ElementName=UserGrid}" />
<Label Content="City" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,86,0,0" x:Name="label2_Copy1" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,115,0,0" x:Name="txtSTate" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.State, ElementName=UserGrid}" />
<Label Content="State" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,113,0,0" x:Name="label2_Copy2" VerticalAlignment="Top" />
</Grid>
</Window>
View Model : UserViewMOdel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using TestApplication.Model;
using System.Windows.Input;
namespace TestApplication.ViewModel
{
class UserViewModel
{
private IList<User> _UsersList;
public UserViewModel()
{
_UsersList = new List<User>
{
new User{UserId = 1,FirstName="Raj",LastName="Beniwal",City="Delhi",State="DEL",Country="INDIA"},
new User{UserId=2,FirstName="Mark",LastName="henry",City="New York", State="NY", Country="USA"},
new User{UserId=3,FirstName="Mahesh",LastName="Chand",City="Philadelphia", State="PHL", Country="USA"},
new User{UserId=4,FirstName="Vikash",LastName="Nanda",City="Noida", State="UP", Country="INDIA"},
new User{UserId=5,FirstName="Harsh",LastName="Kumar",City="Ghaziabad", State="UP", Country="INDIA"},
new User{UserId=6,FirstName="Reetesh",LastName="Tomar",City="Mumbai", State="MP", Country="INDIA"},
new User{UserId=7,FirstName="Deven",LastName="Verma",City="Palwal", State="HP", Country="INDIA"},
new User{UserId=8,FirstName="Ravi",LastName="Taneja",City="Delhi", State="DEL", Country="INDIA"}
};
}
public IList<User> Users
{
get { return _UsersList; }
set { _UsersList = value; }
}
private ICommand mUpdater;
public ICommand UpdateCommand
{
get
{
if (mUpdater == null)
mUpdater = new Updater();
return mUpdater;
}
set
{
mUpdater = value;
}
}
private class Updater : ICommand
{
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
}
#endregion
}
}
}
You need to initialize the DataContext of your View. You can do this in the ctor of your MainPage.
I assume here that the UserViewModel is the ViewModel for your MainPage.
public MainPage() {
InitializeComponents();
this.DataContext = new UserViewModel();
}
I have got a Listview Item with a Gridview Child, bound to a List of Objects.
Below the Gridview I have got texboxes to edit the content of the Gridview (bound to the Gridview).
I can add new content (which is displayed in the GridView).
When i edit content, it is in fact edited (in the object list) but not displayed in the Gridview (the GridView does not seem to update)
xaml code:
<!-- ========= -->
<!-- root Grid -->
<!-- ========= -->
<Grid x:Name="root" Margin="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- ========= -->
<!-- Data Grid -->
<!-- ========= -->
<ListView x:Name="dataGrid" Grid.Row="0" Grid.ColumnSpan="2" ItemsSource="{Binding}">
<ListView.View>
<GridView>
<!-- first solution -->
<GridViewColumn x:Name="gridColumnName" Header="Name" Width="160">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!-- second solution -->
<GridViewColumn x:Name="gridColumnPath" Header="Path" DisplayMemberBinding="{Binding Path=Path}" Width="490" />
</GridView>
</ListView.View>
</ListView>
<!-- ========= -->
<!-- Edit Menu -->
<!-- ========= -->
<Label Content="Name:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
<TextBox x:Name="txtBoxName" Grid.Row="1" Grid.Column="1" Width="250" VerticalAlignment="Bottom" HorizontalAlignment="Left"
DataContext="{Binding ElementName=dataGrid, Path=SelectedItem}"
Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="Path:" Grid.Row="2" Grid.Column="0" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
<TextBox x:Name="txtBoxPath" Grid.Row="2" Grid.Column="1" VerticalAlignment="Bottom" HorizontalAlignment="Stretch"
DataContext="{Binding ElementName=dataGrid, Path=SelectedItem}"
Text="{Binding Path=Path, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
Object List class:
class ItemList : ObservableCollection<LdapItem>
{
public ItemList()
: base()
{
}
}
Object class:
class LdapItem : INotifyPropertyChanged
{
#region constructor
public LdapItem(String name, String path)
{
this.iD = Guid.NewGuid().ToString();
this.name = name;
this.path = path;
}
#endregion
#region public proterties
public String ID
{
get { return iD; }
}
public String Name
{
get { return name; }
set { name = value; }
}
public String Path
{
get { return path; }
set { path = value; }
}
#endregion
#region public methods
public void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
#endregion
#region private variables
private String name = String.Empty;
private String path = String.Empty;
private String iD = String.Empty;
#endregion
public event PropertyChangedEventHandler PropertyChanged;
}
any ideas why updating the GridView doesnt work?
If you have a number of models use a base class that implements INPC. Then change your property changed event handler to:
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
This will eliminate the need to specify the model property being changed. Reduces the number of misspelling errors or forgetting to put the name in. Still needs to call this.OnPropertyChanged() though which you are missing in several setters.
The ItemList class doesn't make sense. It could be replaced with:
public ObservableCollection<LdapItem> LdapItems
it seems like you forgot to fire the OnPropertyChangedEvent when your property changes:
public String Name
{
get { return name; }
set {
name = value;
OnPropertyChanged("Name");
}
}
If you don't fire the PropertyChanged event, WPF will not be able to see if the object has changed.