WPF MVVM ListView does not update when changing in MYSQL - c#

I am new to WPF and MVVM, ListView does not get updated when changing item in Database. Does anyone have any example on how they accomplished this?
Here is my Listview:
<ListView DataContext="{Binding Source={StaticResource changpassVM}, UpdateSourceTrigger=Default}" BorderBrush="Black" Grid.Row="1" Name="lstUser" ItemsSource="{Binding TableFromMySqlEdit,UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding Path= SelectChangPass,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
IsSynchronizedWithCurrentItem = "True"
>
<ListView.View >
<GridView>
<GridViewColumn local:GridViewColumnVisibilityManager.IsVisible="False" Header="Id" HeaderContainerStyle="{StaticResource GridViewHeaderStyle }" DisplayMemberBinding="{Binding Id}" />
<GridViewColumn HeaderContainerStyle="{StaticResource GridViewHeaderStyle }" DisplayMemberBinding="{Binding Name}" Width="Auto" Header="Tên Người Dùng" />
<GridViewColumn HeaderContainerStyle="{StaticResource GridViewHeaderStyle }" DisplayMemberBinding="{Binding Pass,UpdateSourceTrigger=PropertyChanged}" Width="Auto" Header="Mật Khẩu" />
<GridViewColumn HeaderContainerStyle="{StaticResource GridViewHeaderStyle }" DisplayMemberBinding="{Binding Address}" Width="Auto" Header="Địa Chỉ" />
<GridViewColumn HeaderContainerStyle="{StaticResource GridViewHeaderStyle }" DisplayMemberBinding="{Binding Email}" Header="Email" Width="Auto"/>
<GridViewColumn HeaderContainerStyle="{StaticResource GridViewHeaderStyle}" DisplayMemberBinding="{Binding Createdate}" Header="Ngày Tạo" Width="Auto"/>
</GridView>
</ListView.View>
</ListView>
this is my viewmodel:
public class changPassViewModel : INotifyPropertyChanged
{
#region property
// private DataTable _TableFromMySql;
private ObservableCollection<User> _TableFromMySql;
private readonly UserRepository ur;
private readonly changPassUser chuser;
private ICommand _editchangUserCmd;
#endregion end property
#region intialiti
public changPassViewModel()
{
ur = new UserRepository();
//_TableFromMySql = new List<changPassUser>
// {
// new changPassUser {ID=1, Name ="Pro1", Pass="10"},
// new changPassUser{ID=2, Name="BAse2", Pass="12"}
// };
chuser = new changPassUser();
// _TableFromMySql = ur.get_user_DataTable();
_TableFromMySql = ur.getData();
//this.DataContext =
_editchangUserCmd = new RelayCommand(Edit, CanEdit);
}
#endregion intia
#region
public int Id
{
get
{
return chuser.user_Id ;
}
set
{
chuser.user_Id = value;
OnPropertyChanged("Id");
}
}
public string Name
{
get
{
return chuser.user_Name;
}
set
{
chuser.user_Name = value;
OnPropertyChanged("Name");
}
}
public string Pass
{
get
{
return chuser.user_Pass;
}
set
{
chuser.user_Pass = value;
OnPropertyChanged("Pass");
}
}
public string Email
{
get
{
return chuser.user_Email;
}
set
{
chuser.user_Email = value;
OnPropertyChanged("Email");
}
}
public string Address
{
get
{
return chuser.user_Address;
}
set
{
chuser.user_Address = value;
OnPropertyChanged("Address");
}
}
#endregion
#region ListView
public ObservableCollection<User> TableFromMySqlEdit
{
get
{
return _TableFromMySql;
}
set
{
_TableFromMySql = value;
// OnPropertyChanged("TableFromMySqlEdit");
}
}
//public IList<changPassUser> TableFromMySql
//{
// get
// {
// return _TableFromMySql;
// }
// set
// {
// _TableFromMySql = value;
// }
//}
#endregion end ListView
// private ICommand mUpdater;
public ICommand EditPassuser
{
get
{
//if (_editchangUserCmd == null){
// mUpdater = new Updater();
return _editchangUserCmd;
// return mUpdater;
}
set
{
_editchangUserCmd = value;
}
}
public bool CanEdit(object obj)
{
if (Name != string.Empty && Pass != string.Empty && Pass != null)
return true;
return false;
}
public void Edit(object obj)
{
string a = "";
DateTime dt_edit = DateTime.Now;
//int Index;
// Index = UserRepository.GetIndex();
for (int i = 0; i < TableFromMySqlEdit.Count; i++)
if (TableFromMySqlEdit[i].Id == Id)
{
a = _TableFromMySql[i].Pass;
}
var user = new User
{
Id = Id,
// Name = Name,
Pass = Pass,
// Email = Email,
// Address = Address,
Modifieddate =dt_edit.ToString(),
// Status = 0
};
if (ur.Edit(user))
{
// TableFromMySqlEdit. (user);
// GetIndex(Id);
// _TableFromMySql[user.Id] = user.Pass;
// TableFromMySqlEdit = _TableFromMySql;
// Pass = user.Pass;
for (int i = 0; i < TableFromMySqlEdit.Count; i++)
if (TableFromMySqlEdit[i].Id == Id)
{
TableFromMySqlEdit[i].Pass = Pass;
}
ResetUser();
MessageBox.Show("Thêm người dùng thành công !");
}
else
MessageBox.Show("Thêm thất bại !");
}
/* private class Updater : ICommand
{
#region ICommand Members
private changPassUser changUser;
public Updater()
{
changUser = new changPassUser();
}
public bool CanExecute(object parameter)
{
// if (changUser.Name != string.Empty && changUser.Name != null)// && us.PASS != string.Empty)
// if (TableFromMySql.Count > 0)
return true;
// return false;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
MessageBox.Show("Bạn có chắc muốn đóng?");
}
#endregion
}
*/
public User SelectChangPass
{
set
{
Id = value.Id;
Name = value.Name;
Address = value.Address;
Email = value.Email;
// CreateDate = value.user_;
// ModifiedDate = value.Modifieddate;
// Status = value.Status;
Pass = value.Pass;
}
}
private int GetIndex(int Id)
{
for (int i = 0; i < TableFromMySqlEdit.Count; i++)
if (TableFromMySqlEdit[i].Id == Id)
{
TableFromMySqlEdit[i].Pass = Pass;
}
return -1;
}
private void ResetUser()
{
// Id = 0;
Name = string.Empty;
Pass = string.Empty;
Address = string.Empty;
Email = string.Empty;
// MobileNumber = 0;
}
#region INotifyPropertyChanged Members
/// <summary>
/// Event to which the view's controls will subscribe.
/// This will enable them to refresh themselves when the binded property changes provided you fire this event.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// When property is changed call this method to fire the PropertyChanged Event
/// </summary>
/// <param name="propertyName"></param>
public void OnPropertyChanged(string propertyName)
{
//Fire the PropertyChanged event in case somebody subscribed to it
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
This is my model:
public int Id { get; set; }
public string Name { get; set; }
public string Pass { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public string Createdate { get; set; }
public string Modifieddate { get; set; }
public int Status { get; set; }

Related

Telerik datagrid Refresh data: Button in view is working but event not

I struggle to refresh the data attached to the RADdatagrid. The view with the Datagrid shows the position of a team in a competition. Every time a new game is finished the view has to be updated automatically. The data is stored in a sqlite database and a simple sql query gets the positions from the database. A button in the view that calls the query method does the job but I want to update the grid directly after the finished game is stored. I implemented INotifyPropertyChanged but no result. I also tried to fire the button_click event but that also didn't bring me the result. I want to do this right but I am open to a quick and dirty solution. Here is a bit of my code:
<StackPanel Grid.Row="2" Orientation="Horizontal">
<TextBlock Grid.Row="2" Margin="40,0,0,5">Team Ranking</TextBlock>
<Button x:Name="RefreshViewButton" Command="{Binding Path=RefreshView}" Margin="40 0 0 0 " Click="RefreshViewButton_Click">Refresh</Button>
</StackPanel>
<StackPanel Grid.Row="6" Margin="0, 0, 50, 0" VerticalAlignment="Stretch">
<telerikGrid:RadDataGrid
AutoGenerateColumns="False"
x:Name="Datagrid"
BorderThickness="0"
ItemsSource="{x:Bind ViewModel.TeamResult, Mode=TwoWay}"
ColumnDataOperationsMode="Flyout"
GridLinesVisibility="None"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
UserEditMode="None" >
<telerikGrid:RadDataGrid.Columns>
<telerikGrid:DataGridNumericalColumn PropertyName="Rank" Header="Rank" SizeMode="Auto"/>
<telerikGrid:DataGridTextColumn PropertyName="Team_Naam" Header="TeamNaam" SizeMode="Auto"/>
<telerikGrid:DataGridTextColumn PropertyName="WedstrijdPunten" Header="WP" CanUserEdit="False" CanUserFilter="False" CanUserGroup="False" CanUserReorder="False" CanUserResize="False" CanUserSort="False" SizeMode="Auto" />
<telerikGrid:DataGridTextColumn PropertyName="PuntenVoor" Header="GP" SizeMode="Auto"/>
</telerikGrid:RadDataGrid.Columns>
</telerikGrid:RadDataGrid>
</StackPanel>
This is my view:
public sealed partial class TeamTotals : Page
{
public TeamResultsViewModel ViewModel { get; set; } = new TeamResultsViewModel();
public TeamTotals()
{
DataContext = ViewModel;
this.InitializeComponent();
}
public void RefreshViewButton_Click(object sender, RoutedEventArgs e)
{
ViewModel.LoadTeamResultsData();
}
}
My ViewModel:
public class TeamResultsViewModel : TeamModel
{
//public List<TeamModel> TeamResult = new List<TeamModel>();
public ObservableCollection<TeamModel> TeamResult = new ObservableCollection<TeamModel>();
TeamModel tm = new TeamModel();
public TeamResultsViewModel()
{
LoadTeamResultsData();
tm.PropertyChanged += Tm_PropertyChanged;
}
private void Tm_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
throw new NotImplementedException();
}
public void LoadTeamResultsData()
{
int i = 0;
if(TeamResult != null)
{
TeamResult.Clear();
}
try
{
string sql = "Select Team_Naam, WedstrijdPunten, PuntenVoor, PuntenTegen FROM Team WHERE KlasseId = 1 " +
"ORDER BY WedstrijdPunten DESC, PuntenVoor DESC LIMIT 10;";
var resultaat = SqliteDataAccess.LoadData<TeamModel>(sql, new Dictionary<string, object>());
foreach (var x in resultaat)
{
TeamResult.Add(x);
x.Rank = i++;
}
}
catch (Exception ex)
{
var messagedialog2 = new MessageDialog($"{ex}");
_ = messagedialog2.ShowAsync();
}
return;
}
}
and the model:
public class TeamModel : INotifyPropertyChanged
{
private int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
private int _klasseId;
public int KlasseId
{
get { return _klasseId; }
set { _klasseId = value; }
}
private string _team_naam;
public string Team_Naam
{
get { return _team_naam; }
set { _team_naam = value; }
}
private int _coachId;
public int CoachId
{
get { return _coachId; }
set { _coachId = value; }
}
private int _clubId;
public int ClubId
{
get { return _clubId; }
set { _clubId = value; }
}
private int _puntenVoor;
public int PuntenVoor
{
get { return _puntenVoor; }
set { _puntenVoor = value; }
}
private int _puntenTegen;
public int PuntenTegen
{
get { return _puntenTegen; }
set { _puntenTegen = value; }
}
private int _wedstrijdPunten;
public int WedstrijdPunten
{
get { return _wedstrijdPunten; }
set
{
_wedstrijdPunten = value;
OnPropertyChanged("WedstrijdPunten");
}
}
private int _rank;
public int Rank
{
get { return _rank; }
set { _rank = value; }
}
public List<SpelerModel> TeamLeden { get; set; } = new List<SpelerModel>();
public string Standen => $"{Team_Naam} : {PuntenVoor}";
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public override string ToString()
{
return Standen;
}
}

Collection View Refreshing issue While Selecting Item in Xamarin Forms

I have implemented horizontal list using collection view in Xamarin forms. The Underline doesn't come properly it will be late while selecting Item. The Refreshing is too late. AS you can see in the following Video
My Xaml Code
<CollectionView
x:Name="rooms_List"
IsEnabled="True"
SelectedItem="{Binding SelectedRoom}"
SelectionChangedCommand="{Binding Source={x:Reference ThePage}, Path= BindingContext.RoomChanged}"
ItemsLayout = "HorizontalList"
SelectionChanged="RoomCollectionSelectionChanged"
BackgroundColor = "white"
HeightRequest="50"
SelectionMode="Single"
HorizontalScrollBarVisibility="Never"
ItemsSource="{Binding RoomList}">
<CollectionView.ItemTemplate >
<DataTemplate>
<Grid>
<StackLayout VerticalOptions="Start" Orientation="Vertical">
<Label Text ="{Binding RoomName}" Padding="20,10,20,0" />
<BoxView x:Name="line" HeightRequest="3" IsVisible="{Binding IsSelected}" BackgroundColor="#1484B8" WidthRequest="5" Margin="18,0,15,0" />
</StackLayout>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
My Xaml.cs RoomCollectionSelectionChanged
private void RoomCollectionSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection.Count == 0)
{
room_image.IsVisible = true;
}
else
{
var selectedItem = e.CurrentSelection.FirstOrDefault() as Room;
selectedRoom = selectedItem.RoomName;
if (selectedRoom == "All")
{
room_image.IsVisible = false;
}
else if (e.PreviousSelection.Count == 1)
{
var previousItem = (e.PreviousSelection.FirstOrDefault() as Room)?.RoomName;
if (previousItem != "")
{
room_image.IsVisible = true;
room_image.Source = selectedItem.RoomImage;
}
}
else
{
room_image.IsVisible = true;
room_image.Source = selectedItem.RoomImage;
}
}
}
My ViewModel
private ObservableCollection<Room> roomList { get; set; }
public ObservableCollection<Room> RoomList
{
get { return roomList; }
set
{
roomList = value;
OnPropertyChanged(nameof(RoomList));
}
}
private Room selectedRoom { get; set; }
public Room SelectedRoom
{
get { return selectedRoom; }
set
{
selectedRoom = value;
}
}
public bool isSelected { get; set; }
public bool IsSelected
{
get { return isSelected; }
set
{
if (value != isSelected)
{
isSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
}
private Room previousSelectedRoom;
private void SelectedRoomEvent()
{
if (SelectedRoom != null)
{
DevicePage.checkRoom = true;
string RoomName = SelectedRoom.RoomName;
if (RoomName.Equals("All"))
{
GetDeviceAndRoomData();
}
else
{
int RoomId = SelectedRoom.RoomId;
if (previousSelectedRoom != null)
{
previousSelectedRoom.IsSelected = false;
}
previousSelectedRoom = SelectedRoom;
previousSelectedRoom.IsSelected = true;
}
}
My Model
public class Room
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[JsonProperty("roomId")]
public int RoomId { get; set; }
[JsonProperty("serialNumber")]
public string SerialNumber { get; set; }
[JsonProperty("roomName")]
public string RoomName { get; set; }
[JsonProperty("roomImage")]
public string RoomImage { get; set; }
[JsonIgnore]
public bool IsSelected { get; set; }
}
Please give suggestions how to fix this enter image description here
I see you use e. PreviousSelection in your code. That is better than what I was doing in my repository, so I have modified github ToolmakerSteve - repo XFIOSHorizCollViewScrollBug to use that.
I made changes in several places in this file:
using System.Collections.ObjectModel;
using System.Linq;
using Xamarin.Forms;
namespace XFIOSHorizCollViewScrollBug
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
InitRoomList();
BindingContext = this;
// After set BindingContext, so RoomCollectionSelectionChanged gets called.
var room = RoomList[0];
rooms_List.SelectedItem = room;
}
public ObservableCollection<Room> RoomList { get; set; }
private void RoomCollectionSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var previousItem = e.PreviousSelection.FirstOrDefault() as Room;
DeselectRoom(previousItem);
var selectedItem = e.CurrentSelection.FirstOrDefault() as Room;
SelectRoom(selectedItem);
}
private void DeselectRoom(Room room)
{
if (room != null)
{
room.IsSelected = false;
}
}
private void SelectRoom(Room room)
{
if (room != null) {
room.IsSelected = true;
rooms_List.ScrollTo(room, position: ScrollToPosition.Center, animate: false);
}
}
string[] roomNames = new string[] {
"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"
};
private void InitRoomList()
{
var rooms = new ObservableCollection<Room>();
foreach (var name in roomNames) {
rooms.Add(new Room(name));
}
RoomList = rooms;
}
}
}
The other files are the same as in my answer to your previous question.
Please download my repository, build and run it, verify that it works. The change to underline happens INSTANTLY - as soon as you click on an item.
Then compare that to your code. Change your code until it matches what the working repo does.

WPF Observable Collection not updating

i'm quite the rookie in the WPF enviroment
i have been scouring for a solution, although i'm sure it's just something very basic i have yet to understand
I'm trying to make use of Observable collection to update a Listview
I have added a method in the viewmodel, i need to call from outside code to add another item to the list.
When i call method addTask in the ViewModel with debugger on, i can see it counts up 1 item in the list. But it doesn't add it to the ListView
Model:
public class Tasks : INotifyPropertyChanged
{
private string taskName;
private string fromTime;
private string toTime;
private string message;
private string taskCreator;
public string TaskName
{
get
{
return taskName;
}
set
{
taskName = value;
OnPropertyChanged("TaskName");
}
}
public string FromTime
{
get
{
return fromTime;
}
set
{
fromTime = value;
OnPropertyChanged("FromTime");
}
}
public string ToTime
{
get
{
return toTime;
}
set
{
toTime = value;
OnPropertyChanged("ToTime");
}
}
public string Message
{
get
{
return message;
}
set
{
message = value;
OnPropertyChanged("Message");
}
}
public string TaskCreator
{
get
{
return taskCreator;
}
set
{
taskCreator = value;
OnPropertyChanged("TaskCreator");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
the ViewModel:
class TasksViewModel
{
public TasksViewModel()
{
{
_UsersList.Add(new Tasks() { TaskName = "TaskName1", FromTime = "03:00", ToTime = "07:00", TaskCreator = "TaskCreator1", Message = "Hello" });
_UsersList.Add(new Tasks() { TaskName = "TaskName2", FromTime = "03:00", ToTime = "07:00", TaskCreator = "TaskCreator2", Message = "Hello" });
_UsersList.Add(new Tasks() { TaskName = "TaskName3", FromTime = "03:00", ToTime = "07:00", TaskCreator = "TaskCreator3", Message = "Hello" });
};
}
public ObservableCollection<Tasks> Tasks
{
get { return _UsersList; }
}
public ObservableCollection<Tasks> _UsersList { get; set; } = new ObservableCollection<Tasks>();
public void addTask(string taskName, string fromTime, string toTime, string taskCreator, string message)
{
_UsersList.Add(new Tasks() { TaskName = taskName, FromTime = fromTime, ToTime = toTime, TaskCreator = taskCreator, Message = message });
}
The list view i want to update (Xaml)
<ListView Name="TaskGrid1" Grid.Row="1" Grid.Column="1" Margin="4,4,12,13" ItemsSource="{Binding Tasks}" RenderTransformOrigin="0.5,0.5" FontSize="30" >
<ListView.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="0"/>
<TranslateTransform/>
</TransformGroup>
</ListView.RenderTransform>
<ListView.View>
<GridView x:Name="List00000600">
<GridViewColumn Header="Tid" DisplayMemberBinding="{Binding FromTime}" Width="100"/>
<GridViewColumn Header="Opgave" DisplayMemberBinding="{Binding TaskName}" Width="350" />
<GridViewColumn Header="Opretter" DisplayMemberBinding="{Binding TaskCreator}" Width="120" />
</GridView>
</ListView.View>
</ListView>
I have no idea how you've assigned viewmodel in app.xaml.
Just open the xaml file, which holds your listview and build your window as usual:
<Window
... (rest of xmlns)
xmlns:MyViewModels="clr-namespace:YourViewModelNamespace"
>
<Window.DataContext>
<MyViewModels:TasksViewModel/>
</Window.DataContext>
<Grid/Or any container>
...
<ListView... />
</Grid/Or any container
</Window>
As mentioned, replace _UserList with Tasks.
Your async TasksCreate() is creating new instance of TasksViewModel so it will never update current one.
PS: you can obtain viewmodel by:
// this function belongs to mainwindow/anywindow
public void CodeBehindClickEvent(object sender, RoutedEventArgs e)
{
var VM = (TasksViewModel)this.DataContext;
VM.addTask("blabla", ...)
VM.TasksCreate();
}

How to bind WPF datagrid to a property in a contained ObservableCollection

I am fairly new to C# and WPF so any help will be much appreciated.
UPDATE:
I have two objects, PurchaseOrder (PO) and PurchaseOrderDetails (POD).
PO contains an ObservableCollection of POD.
I am able to get all data needed from my database.
So when the OfficeAdmin window loads , I get all Purchase Orders from the database table and display it in the PO datagrid, when a selection is made in the dgPurchaseOrder, the details of the current Purchase Order is displayed in the dgPODescription.
However i would like to display the 'PODate' property of POD in dgPurchaseOrders, I took a look at the link #Default provided in the comments but I'm still not getting the binding to work, what am I missing?
public class PurchaseOrder : INotifyPropertyChanged
{
int _id;
string _customerName;
int _customerId;
int _purchaseOrderNumber;
int _purchaseOrderDetailsId;
private ObservableCollection<Customer> _customer;
private ObservableCollection<PurchaseOrderDetails> _purchaseOrderDetails;
public ObservableCollection<Customer> Customer
{
get { return _customer; }
set
{
_customer = value;
OnPropertyChanged("Customer");
}
}
public PurchaseOrder()
{
_customerName = String.Empty;
}
public int Id
{
get { return _id; }
set
{
_id = value;
OnPropertyChanged("Id");
}
}
public string CustomerName
{
get { return _customerName; }
set
{
_customerName = value;
OnPropertyChanged("CustomerName");
}
}
public int CustomerId
{
get { return _customerId; }
set
{
_customerId = value;
OnPropertyChanged("CustomerId");
}
}
public int PurchaseOrderId
{
get { return _purchaseOrderDetailsId; }
set
{
_purchaseOrderDetailsId = value;
OnPropertyChanged("PurchaseOrderDetailsId");
}
}
public int PurchaseOrderNumber
{
get { return _purchaseOrderNumber; }
set
{
_purchaseOrderNumber = value;
OnPropertyChanged("PurchaseOrderDetailsId");
}
}
public ObservableCollection<PurchaseOrderDetails> PurchaseOrderDetails
{
get { return _purchaseOrderDetails; }
set
{
_purchaseOrderDetails = value;
OnPropertyChanged("PurchaseOrderDetails");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
public class PurchaseOrderDetails : INotifyPropertyChanged
{
int _id;
int _orderNumber;
string _customerName;
int _costPrice;
int _quantity;
int _totalAmount;
int _vat;
string _date;
string _deliveryDate;
int _productId;
string _productName;
public PurchaseOrderDetails()
{
_customerName = string.Empty;
_productName = string.Empty;
}
public int Id
{
get { return _id; }
set
{
_id = value;
OnPropertyChanged("Id");
}
}
public int OrderNumber
{
get { return _orderNumber; }
set
{
_orderNumber = value;
OnPropertyChanged("Quantity");
}
}
public string CustomerName
{
get { return _customerName; }
set
{
_customerName = value;
OnPropertyChanged("CustomerName");
}
}
public string PODate
{
get { return _date; }
set
{
_date = value;
OnPropertyChanged("PODate");
}
}
public string DeliveryDate
{
get { return _deliveryDate; }
set
{
_deliveryDate = value;
OnPropertyChanged("DeliveryDate");
}
}
public int ProductId
{
get { return _productId; }
set
{
_productId = value;
OnPropertyChanged("ProductId");
}
}
public string ProductName
{
get { return _productName; }
set
{
_productName = value;
OnPropertyChanged("ProductName");
}
}
public int CostPrice
{
get { return _costPrice; }
set
{
_costPrice = value;
OnPropertyChanged("CostPrice");
}
}
public int Quantity
{
get { return _quantity; }
set
{
_quantity = value;
OnPropertyChanged("Quantity");
}
}
public int Vat
{
get { return _vat; }
set
{
_vat = value;
OnPropertyChanged("Vat");
}
}
public int TotalAmount
{
get { return _totalAmount; }
set
{
_totalAmount = value;
OnPropertyChanged("TotalAmount");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
OfficeAdmin.xaml
<DataGrid x:Name="dgPurchaseOrder"
Style="{StaticResource AdminGridStyle}"
SelectionChanged="dgPurchaseOrder_SelectionChanged"
MouseUp="dgPurchaseOrder_MouseUp">
<DataGrid.Columns>
<DataGridTextColumn x:Name="dgPOCustomerName"
Header="Customer Name"
Binding="{Binding CustomerName}"
Width="1*" />
<DataGridTextColumn x:Name="PoPurchaseOrderNumber"
Header="Order Number"
Binding="{Binding PurchaseOrderNumber}"
Width="1*" />
<DataGridTemplateColumn Header="Date">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding PurchaseOrderDetails.PODate}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<DataGrid x:Name="dgPODescription"
Style="{StaticResource AdminGridStyle}"
ItemsSource="{Binding PurchaseOrderDetails}">
<DataGrid.Columns>
<DataGridTextColumn x:Name="PoProduct"
Header="Product"
Binding="{Binding ProductName}"
Width="1*" />
<DataGridTextColumn x:Name="PoQuantity"
Header="Quantity"
Binding="{Binding Quantity}"
Width="1*" />
<DataGridTextColumn x:Name="PoCostPrice"
Header="Cost Price"
Binding="{Binding CostPrice}"
Width="1*" />
<DataGridTextColumn x:Name="PoTotalAmount"
Header="Total Amount"
Binding="{Binding TotalAmount}"
Width="1*" />
<DataGridTextColumn x:Name="PoVat"
Header="Vat"
Binding="{Binding Vat}"
Width="1*" />
<DataGridTextColumn x:Name="PoDate"
Header="Date"
Binding="{Binding PODate}"
Width="1*" />
<DataGridTextColumn x:Name="DeliveryDate"
Header="Delivery Date"
Binding="{Binding DeliveryDate}"
Width="1*" />
</DataGrid.Columns>
</DataGrid>
OfficeAdmin.xaml.cs
private void Window_Loaded(object sender, RoutedEventArgs e)
{
dgPurchaseOrder.ItemsSource = vm.getAllPurchasOrders();
dgPurchaseOrder.SelectedIndex = 0;
dgPODescription.ItemsSource = vm.PurchaseOrderDetails;
}
private void dgPurchaseOrder_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var purchaseOrder = dgPurchaseOrder.SelectedItem as PurchaseOrder;
if(purchaseOrder!=null)vm.setCurrentPurchaseOrder(purchaseOrder);
dgPODescription.ItemsSource = vm.PurchaseOrderDetails;
}
vmOfficeAdmin.cs
public ObservableCollection<PurchaseOrder> PurchaseOrder { get; set; }
public ObservableCollection<Customer> PurchaseOrderCustomer { get; set;}
public ObservableCollection<PurchaseOrderDetails> PurchaseOrderDetails {get; set; }
public PurchaseOrder CurrentPurchaseOrder { get; set; }
public vmUserManagement()
{
CurrentPurchaseOrder = new PurchaseOrder();
PurchaseOrder = new ObservableCollection<PurchaseOrder>();
PurchaseOrderCustomer = new ObservableCollection<Customer>();
PurchaseOrderDetails = new ObservableCollection<PurchaseOrderDetails>();
}
public ObservableCollection<PurchaseOrder> getAllPurchasOrders()
{
PurchaseOrder = RepoDapper.getAllPurchaseOrders();
return PurchaseOrder;
}
public void setCurrentPurchaseOrder(PurchaseOrder purchaseOrder)
{
CurrentPurchaseOrder = purchaseOrder;
PurchaseOrderDetails.Clear();
CurrentPurchaseOrder.PurchaseOrderDetails = RepoDapper.getPurchaseOrderDetails(CurrentPurchaseOrder.Id);
CurrentPurchaseOrder.Customer = RepoDapper.getPurchaseOrderCustomerDetails(CurrentPurchaseOrder.CustomerId);
foreach (var b in CurrentPurchaseOrder.PurchaseOrderDetails)
{
PurchaseOrderDetails.Add(b);
}
foreach(var d in CurrentPurchaseOrder.Customer)
{
PurchaseOrderCustomer.Add(d);
}
}

Problems with binding an ObservableCollection from inside an Object to ListView

My WPF ListView
<ListView Name="lstTasks" ItemContainerStyle="{StaticResource itemstyle}" ItemsSource="{Binding ElementName=TaskFile,Path=obscollFiles}" SelectionMode="Single">
<ListView.View>
<GridView>
<GridViewColumn Header="Id" DisplayMemberBinding="{Binding TaskId}" />
<GridViewColumn Header="Datum" DisplayMemberBinding="{Binding TaskDate,StringFormat={}{0:dd.MM.yyyy}}" />
<GridViewColumn Header="Startzeit" DisplayMemberBinding="{Binding TaskStartTime,StringFormat=t}" />
<GridViewColumn Header="Endzeit" DisplayMemberBinding="{Binding TaskEndTime,StringFormat=t}" />
<GridViewColumn Header="Dauer" DisplayMemberBinding="{Binding TaskDuration}" />
<GridViewColumn Header="Task" DisplayMemberBinding="{Binding TaskString}" />
</GridView>
</ListView.View>
</ListView>
I just want to bind this ListVIew (as you could expect from the code above to an Object:
public class csTaskFileInfo
{
public DateTime DateOfTasks { get; set; }
public ObservableCollection<csTask> obscollTasks { get; set; }
public csTaskFileInfo()
{
obscollTasks = new ObservableCollection<csTask>();
}
}
And the csTask Class from the ObservableCollection:
[Serializable]
public class csTask:INotifyPropertyChanged
{
private int _TaskId;
private string _TaskString;
private DateTime _TaskDate;
private TimeSpan _TaskStartTime;
private TimeSpan _TaskEndTime;
private TimeSpan _TaskDuration;
[XmlIgnore]
public TimeSpan TaskDuration
{
get { return _TaskDuration; }
set
{
_TaskDuration = value;
Notify("TaskDuration");
}
}
[XmlIgnore]
public TimeSpan TaskEndTime
{
get { return _TaskEndTime; }
set
{
_TaskEndTime = value;
if (TaskEndTime > TaskStartTime)
{
TaskDuration = TaskEndTime - TaskStartTime;
}
Notify("TaskEndTime");
}
}
[XmlIgnore]
public TimeSpan TaskStartTime
{
get { return _TaskStartTime; }
set
{
_TaskStartTime = value;
if (_TaskStartTime < _TaskEndTime)
{
TaskDuration = TaskEndTime - TaskStartTime;
}
Notify("TaskStartDate");
}
}
public DateTime TaskDate
{
get { return _TaskDate; }
set
{
_TaskDate = value;
Notify("TaskDate");
}
}
[XmlElement("TaskDurationString")]
public string TaskDurationString { get { return TaskDuration.ToString(); } set { TaskDuration = TimeSpan.Parse(value); } }
[XmlElement("TaskEndTimeString")]
public string TaskEndTimeString { get { return TaskEndTime.ToString(); } set { TaskEndTime = TimeSpan.Parse(value); } }
[XmlElement("TaskStartTimeString")]
public string TaskStartTimeString { get { return TaskStartTime.ToString(); } set { TaskStartTime = TimeSpan.Parse(value); } }
public string TaskString
{
get { return _TaskString; }
set
{
_TaskString = value;
Notify("TaskString");
}
}
public int TaskId
{
get { return _TaskId; }
set
{
_TaskId = value;
Notify("TaskId");
}
}
public csTask(int TaskId, string TaskString,DateTime TaskDate)
{
this.TaskId = TaskId;
this.TaskString = TaskString;
this.TaskDate = TaskDate;
}
public csTask()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void Notify(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
As you can see, INotifyPropertyChanged is already implemented.
The part why I am a little bit confused:
In an earlier version when I only used an ObservableCollection the binding was working.
Since I am using an Object where the Collection exists inside of that Object i am not able to get it working.
Is there missing something?
The Datacontext of my MainWindow where i am using that object is already set to itself.
this.Datacontext = this;
Some hints or pointings to a mistake would be very nice :)
Thanks a lot!
Greetings
Daniel
Edit:
I implemented the INotifyPropertyChanged inside of csTask.
(using it at ObservableCollection inside of csTaskFile)
The Code of my MainWindow as you wished :) :
FileSystemWatcher FileWatcher;
public csTaskFileInfo TaskFile { get; set; }
public List<FileInfo> obscollFiles { get; set; }
private string _FolderPath;
public string FolderPath
{
get { return _FolderPath; }
set
{
_FolderPath = value;
Notify("FolderPath");
}
}
public DirectoryInfo FolderDirectory { get; set; }
public MainWindow()
{
InitializeComponent();
TaskFile = new csTaskFileInfo();
TaskFile.DateOfTasks = DateTime.Now;
obscollFiles = new List<FileInfo>();
this.DataContext = this;
RegistryKey _RegKey = Registry.CurrentUser.OpenSubKey("Software\\WTT");
if (_RegKey == null)
{
FolderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\WTT_Files";
}
else
{
FolderPath = (string)_RegKey.GetValue("FolderDestination") + "\\WTT_Files";
}
if (Directory.Exists(FolderPath) == false)
{
Directory.CreateDirectory(FolderPath);
}
FolderDirectory = new DirectoryInfo(FolderPath);
FileWatcher = new FileSystemWatcher(FolderPath,"*.xml");
FileWatcher.Created += new FileSystemEventHandler (FileWatcher_Changed);
FileWatcher.Deleted += new FileSystemEventHandler (FileWatcher_Changed);
//FileWatcher.Changed += new FileSystemEventHandler(FileWatcher_Changed);
FileWatcher.Renamed += new RenamedEventHandler(FileWatcher_Changed);
FileWatcher.EnableRaisingEvents = true;
FileWatcher_Changed(null,null);
var _temp = from n in obscollFiles
where n.Name == (DateTime.Today.ToShortDateString() + ".xml")
select n;
if (_temp.Count() == 1)
{
lstFiles.SelectedItem = _temp.Single() as FileInfo;
}
}
private void FileWatcher_Changed(object sender, FileSystemEventArgs e)
{
obscollFiles = FolderDirectory.GetFiles("*.xml").ToList();
Notify("obscollFiles");
}
private void NewTask_Click(object sender, RoutedEventArgs e)
{
TaskStringWindow _newTaskStringWindow = new TaskStringWindow();
_newTaskStringWindow.Owner = this;
_newTaskStringWindow.txtEingabe.Focus();
_newTaskStringWindow.ShowDialog();
if (_newTaskStringWindow.DialogResult == true)
{
csTask _newTask = new csTask();
if (TaskFile.obscollTasks != null && TaskFile.obscollTasks.Count > 0)
{
csTask _previousTask;
_previousTask = TaskFile.obscollTasks.Last();
_previousTask.TaskEndTime = TimeSpan.Parse(DateTime.Now.ToLongTimeString());
_newTask.TaskId = _previousTask.TaskId + 1;
_newTask.TaskDate = TaskFile.DateOfTasks;
_newTask.TaskStartTime = TimeSpan.Parse(DateTime.Now.ToLongTimeString());
}
else
{
_newTask.TaskId = 1;
_newTask.TaskDate = DateTime.Now;
_newTask.TaskStartTime = TimeSpan.Parse(DateTime.Now.ToLongTimeString());
}
_newTask.TaskString = _newTaskStringWindow.txtEingabe.Text;
TaskFile.obscollTasks.Add(_newTask);
//lstTasks.DataContext = TaskFile.obscollTasks;
}
}
private void SaveCurrentFile_Click(object sender, RoutedEventArgs e)
{
XmlSerializer XmlSer = new XmlSerializer(typeof(csTaskFileInfo));
if (Directory.Exists(FolderPath) == false)
{
Directory.CreateDirectory(FolderPath);
}
FileStream stream = new FileStream(FolderPath + #"\" + DateTime.Now.ToShortDateString() + ".xml", FileMode.Create);
XmlSer.Serialize(stream, TaskFile);
stream.Close();
}
private void ResetSearchByDate_Click(object sender, RoutedEventArgs e)
{
//lstTasks.DataContext = TaskFile.obscollTasks;
}
private void LoadFile_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog OpenFile = new OpenFileDialog();
OpenFile.Filter = ("XAML-Dateien |*.xml");
if (OpenFile.ShowDialog(this) == true)
{
TaskFile.obscollTasks.Clear();
FileInfo _tempFileInfo = new FileInfo(OpenFile.FileName);
obscollFiles.Add(_tempFileInfo);
lstFiles.SelectedItem = _tempFileInfo;
}
}
private void LoadFile(FileInfo File)
{
try
{
//XmlSerializer XmlSer = new XmlSerializer(typeof(csTaskFileInfo));
//FileStream stream = new FileStream(File.FullName, FileMode.Open);
//TaskFile = (csTaskFileInfo)XmlSer.Deserialize(stream);
using (FileStream fStream = new FileStream(File.FullName,FileMode.Open))
{
XmlSerializer XmlSer = new XmlSerializer(typeof(csTaskFileInfo));
using (StreamReader sReader = new StreamReader(fStream,Encoding.UTF8))
{
TaskFile = (csTaskFileInfo)XmlSer.Deserialize(sReader);
//lstTasks.DataContext = TaskFile.obscollTasks;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.ToString(),"Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void SetFolder_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.FolderBrowserDialog _SelectFolder = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult _result = _SelectFolder.ShowDialog();
if (_result == System.Windows.Forms.DialogResult.OK)
{
RegistryKey _RegKey = Registry.CurrentUser.OpenSubKey("Software",true);
_RegKey.CreateSubKey("WTT");
_RegKey = _RegKey.OpenSubKey("WTT",true);
_RegKey.SetValue("FolderDestination", _SelectFolder.SelectedPath);
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void Notify(string propertyName)
{
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private void lstFiles_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
TaskFile.obscollTasks.Clear();
LoadFile(lstFiles.SelectedItem as FileInfo);
}
private void HandleDoubleClick(object sender,MouseButtonEventArgs e)
{
TaskChangeData TaskChange = new TaskChangeData(TaskFile.obscollTasks, lstTasks.SelectedItem as csTask);
TaskChange.ShowDialog();
}
Since there is no obscollFiles in TaskFile (there is obscollTasks instead) shouldn't it be
<ListView Name="lstTasks" SelectionMode="Single"
ItemContainerStyle="{StaticResource itemstyle}"
ItemsSource="{Binding Path=TaskFile.obscollTasks}" >
....
?

Categories