WPF Observable Collection not updating - c#

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();
}

Related

Background / Foreground Capability in Custom ListView Items

I have the following functioning code that binds GridViewColumns to data from a custom class:
<ListView Name="lv">
<ListView.View>
<GridView>
<GridViewColumn Header="First" DisplayMemberBinding="{Binding lvi.firstName}"/>
<GridViewColumn Header="Last" DisplayMemberBinding="{Binding lvi.lastName}"/>
</GridView>
</ListView.View>
</ListView>
public class LVItemBox {
public LVItem lvi { get; set; }
}
public class LVItem : INotifyPropertyChanged {
private string _firstName;
private string _lastName;
public string firstName {
get { return _firstName; }
set { SetField(ref _firstName, value); }
}
public string lastName {
get { return _lastName; }
set { SetField(ref _lastName, value); }
}
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged(string propertyName) {PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
LVItem lvi1 = new LVItem {firstName = "John", lastName = "Doe"};
LVItem lvi2 = new LVItem {firstName = "Jane", lastName = "Smith"};
lv.Items.Add(new LVItemBox {lvi = lvi1});
lv.Items.Add(new LVItemBox {lvi = lvi2});
}
}
My dilemma is that I want background / foreground Brush capability within LVItemBox, however if I make LVItemBox extend Control, changing Background/Foreground has no effect:
public class LVItemBox : Control {
public LVItem lvi { get; set; } // data displays
}
...
...
private void changeBackground(object sender, EventArgs e) {
LVItemBox lvib = (LVItemBox)lv.Items[0];
lvib.Background = Brushes.Black; // doesn't work
}
Furthermore, if I extend ListViewItem instead of Control I can get the background change to work, but the data bindings no longer work.
public class LVItemBox : ListViewItem {
public LVItem lvi { get; set; } // data doesn't display
}
...
...
private void changeBackground(object sender, EventArgs e) {
LVItemBox lvib = (LVItemBox)lv.Items[0];
lvib.Background = Brushes.Black; // works
}
Any idea how I can get foreground / background capability within LVItemBox?
Inheriting from Control works if you add the following ItemContainerStyle to your XAML:
<ListView Name="lv">
<ListView.View>
<GridView>
<GridViewColumn Header="First" DisplayMemberBinding="{Binding lvi.firstName}"/>
<GridViewColumn Header="Last" DisplayMemberBinding="{Binding lvi.lastName}"/>
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Background" Value="{Binding Background}" />
</Style>
</ListView.ItemContainerStyle>
</ListView>

WPF MVVM ListView does not update when changing in MYSQL

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; }

Listview Displaying Name space not values from class Phone 8.1 Runtime

I am trying to bind a simple Listview control using the folloiwng
<ListView x:Name="listView" ItemsSource="{Binding}">
<StackPanel Orientation="Horizontal" Width="292" Height="80">
<Border Height="60" Width="60" Margin="10,10,0,10">
<Image Source="/SampleImage.png" Stretch="UniformToFill"/>
</Border>
<StackPanel Orientation="Vertical" VerticalAlignment="Top" Margin="0,10,0,0">
<TextBlock Text="{Binding description}"
Margin="10,0,0,0" Width="180" Height="42"
TextTrimming="WordEllipsis" TextWrapping="Wrap" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding Title}"
Margin="10,2,0,0" Width="180" Height="14"
TextTrimming="WordEllipsis" HorizontalAlignment="Left"
FontSize="9" Opacity="0.49"/>
</StackPanel>
</StackPanel>
</ListView>
But for some reason when I reference my list which is created as such
using Parse;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
namespace Curo.DataModel
{
public class curoLists : INotifyPropertyChanged
{
public curoLists()
{
}
public curoLists(String uniqueId, String title, String subtitle, String imagePath, String description, String content, string type)
{
this.UniqueId = uniqueId;
this.Title = title;
this.Subtitle = subtitle;
this.Description = description;
this.ImagePath = imagePath;
this.Content = content;
this.Type = type;
}
public curoLists(String uniqueId, String title, String subtitle, String imagePath, String description, String content, bool unread, Int32 status)
{
UniqueId = uniqueId;
Title = title;
Subtitle = subtitle;
Description = description;
ImagePath = imagePath;
Content = content;
Unread = unread;
Status = status;
}
private bool _unread;
private string _title;
public string UniqueId { get; private set; }
public string Title
{
get { return _title; }
set
{
_title = value;
NotifyPropertyChanged("Title");
}
}
public string Subtitle { get; private set; }
public string Description { get; private set; }
public string ImagePath { get; private set; }
public string Content { get; private set; }
public int Status { get; private set; }
public string Type { get; private set; }
public string ViewToUse { get; private set; }
public bool Unread
{
get { return _unread; }
set
{
_unread = value;
NotifyPropertyChanged("Unread");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public static async Task<curoLists> CreateFromParseObject(ParseObject parseObject)
{
return await Task.Run<curoLists>(() =>
{
var mlist = new curoLists();
mlist.Title = parseObject.ObjectId;
if (parseObject.ContainsKey("name"))
{
mlist.Title = (string)parseObject["name"];
}
if (parseObject.ContainsKey("description"))
{
mlist.Description = (string)parseObject["description"];
}
if (parseObject.ContainsKey("image"))
{
mlist.ImagePath = (string)parseObject["image"];
}
if (parseObject.ContainsKey("type"))
{
string mtype = (string)parseObject["type"];
if (mtype == "N")
{
mlist.Type = "Notes";
mlist.ViewToUse = "Notes.Xaml";
}
}
return mlist;
});
}
}
}
It does not display the requested data instead it just displays the folowing. I populate my list in the following mannor
List<curoLists> cLists;
public ClientsManage()
{
this.InitializeComponent();
PopulatelistAsync();
}
public async Task PopulatelistAsync()
{
try
{
curoListsDal _db = new curoListsDal();
cLists = await _db.GetListsAync();
listView.ItemsSource = cLists;
}
catch (Exception ex)
{
}
}
But it just displays the name space and not the data Curo.DataModel.CuroLists. When i debug the data it is def their and correct spelling the only thing it complains about when i compiles is on my constructor i do not have the await command but that would not make the data not appear would it?.
ListView is single Column. So you must custom it with GridView. I also add Window_Loaded method with asyn, and own Dal:
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
Loaded="Window_Loaded">
<ListView x:Name="listView">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Game Name"
DisplayMemberBinding="{Binding Description}" />
<GridViewColumn Width="140" Header="Title"
DisplayMemberBinding="{Binding Title}" />
</GridView>
</ListView.View>
</ListView>
</Window>
Code behind:
public partial class MainWindow : Window
{
private List<curoLists> cLists;
public MainWindow()
{
InitializeComponent();
}
// decorate this method with asyn
private async void Window_Loaded(
object sender, RoutedEventArgs e)
{
await PopulatelistAsync();
}
public async Task PopulatelistAsync()
{
try
{
curoListsDal _db = new curoListsDal();
cLists = await _db.GetListsAync();
listView.ItemsSource = cLists;
}
catch (Exception ex)
{
}
}
}
public class curoListsDal
{
public async Task<List<curoLists>> GetListsAync()
{
return await
Task.Run<List<curoLists>>(
() =>
{
Thread.Sleep(2000); // long run
var result = new List<curoLists>();
for (var i = 0; i < 3; i++)
{
var id = Guid.NewGuid().ToString();
var mlist = new curoLists(id,
"title" + id, "subtitle", "imagePath",
"desc", "content", true, 1);
result.Add(mlist);
}
return result;
});
}
}
Hope this help.

How to select one list which is an item of another list c#

How to select only one of lists which is a part of List FeatList? One FeatList item consists of CurrencyTypes and Date. I need to add to CurList only that CurrencyTypes list where Date is equal to ListCtrl3.SelectedItem.
namespace PhoneApp1
{
public class CurrencyOfDate
{
public List<CurrencyType> CurrencyTypes;
public string Date { get; set; }
public override string ToString()
{
return Date;
}
}
public class CurrencyType
{
public string Name { get; set; }
public string Value { get; set; }
public override string ToString()
{
return Name;
}
}
public partial class MainPage : PhoneApplicationPage
{
List<CurrencyType> curList = new List<CurrencyType>();
public event PropertyChangedEventHandler PropertyChanged;
public void InvokePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public List<CurrencyType> CurList
{
get { return curList; }
set
{
curList = value;
InvokePropertyChanged("CurList");
}
}
List<CurrencyOfDate> featList = new List<CurrencyOfDate>();
public List<CurrencyOfDate> FeatList
{
get { return featList; }
set
{
featList = value;
InvokePropertyChanged("FeatList");
}
}
// Constructor
public MainPage()
{
InitializeComponent();
Dispatcher.BeginInvoke(() =>
{
_download_serialized_data("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml");
});
}
private async void _download_serialized_data(string url)
{
HttpClient webclient = new HttpClient();
try
{
var downloadedString =
await
webclient.GetStringAsync(
new Uri("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml"));
XElement xmlData = XElement.Parse(downloadedString);
XNamespace ns = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref";
List<CurrencyOfDate> list = new List<CurrencyOfDate>();
foreach (XElement c in xmlData.Elements(ns + "Cube").Elements(ns + "Cube"))
list.Add(new CurrencyOfDate()
{
Date = c.Attribute("time").Value,
CurrencyTypes =
(from k in xmlData.Elements(ns + "Cube").Elements(ns + "Cube").Elements(ns + "Cube")
select new CurrencyType()
{
Name = k.Attribute("currency").Value,
Value = k.Attribute("rate").Value
}).ToList()
});
FeatList = list;
ListCtrl3.ItemsSource = FeatList;
foreach (var selItem in list.Where(selItem => ListCtrl3.SelectedItem.ToString() == selItem.Date))
{
CurList = selItem.CurrencyTypes.ToList();
FromList.ItemsSource = CurList;
break;
}
}
and xaml:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,511">
<toolkit:ListPicker ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding CurList}"
x:Name="FromList"
Margin="10,0,240,0">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock FontSize="30"
Text="{Binding Name}">
</TextBlock>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
</toolkit:ListPicker>
</Grid>
<Grid>
<toolkit:ListPicker x:Name="ListCtrl3" ItemsSource="{Binding FeatList}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalContentAlignment="Stretch" Margin="230,0,10,0">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding Date}"/>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
</toolkit:ListPicker>
</Grid>

How to bind Selected Items in MVVM

I am using WPF, MVVM and DevExpress GridControl. There are two panels in my MainWindow.xaml. Panle1 has Grid and Panel2 has Textbox. I want that if i select an item from Grid in Panel1 it's name should display in that Panle2 Textbox. Iwrote Code but it is not working. Can you Please help me to solve this?
*In NameModel From Models Folder I wrote:*
private NameModelClass _selectedCustomer;
public NameModelClass SelectedCustomer
{
get { return _selectedCustomer; }
set
{
if (_selectedCustomer != value)
{
_selectedCustomer = value;
LastName = value.LastName;
OnPropertyChanged("SelectedCustomer");
}
}
public List<Namess> ListPerson { get; set; }
void CreateList()
{
ListPerson = new List<Namess>();
for (int i = 0; i < 10; i++)
{
ListPerson.Add(new Namess(i));
}
}
public class Namess
{
public Namess(int i)
{
FirstName = "FirstName" + i;
LastName = "LastName" + i;
Age = i * 10;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
}
In MianWindow.xaml I wrote:
<dxdo:LayoutPanel Caption="Grid" Caption="Panel1" x:Name="abc1">
<Grid>
<dxg:GridControl x:Name="grid" Height="233" ItemsSource="{Binding ListPerson}" AutoGenerateColumns="AddNew" HorizontalAlignment="Left" VerticalAlignment="Top" SelectedItem="{Binding SelectedNames}">
<dxg:GridControl.View>
<dxg:TableView ShowTotalSummary="True"/>
</dxg:GridControl.View>
</dxg:GridControl>
</Grid>
</dxdo:LayoutPanel>
<dxdo:LayoutPanel Caption="Panel2" x:Name="abc1">
<TextBox Width="166" Background="White" Height="33" HorizontalAlignment="Right" VerticalAlignment="Bottom" Text="{Binding Path=LastName}"/>
</dxdo:LayoutPanel>
I am new to MVVM and c#. I f my query is not clear to you please ask me. Thank you.
I do it this way:
private Namess _selectedCustomer;
public Namess SelectedCustomer
{
get { return _selectedCustomer; }
set
{
if (_selectedCustomer != value)
{
_selectedCustomer = value;
OnPropertyChanged("SelectedCustomer");
}
}
public List<Namess> ListPerson { get; set; }
void CreateList()
{
ListPerson = new List<Namess>();
for (int i = 0; i < 10; i++)
{
ListPerson.Add(new Namess(i));
}
}
public class Namess : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
public Namess(int i)
{
FirstName = "FirstName" + i;
LastName = "LastName" + i;
Age = i * 10;
}
public string FirstName { get; set; }
private string _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
if(value==_lastName)
return;
_lastName=value;
OnPropertyChanged("LastName");
}
}
public int Age { get; set; }
}
}
and in your view:
<dxdo:LayoutPanel Caption="Grid" Caption="Panel1" x:Name="abc1">
<Grid>
<dxg:GridControl x:Name="grid" Height="233" ItemsSource="{Binding ListPerson}" AutoGenerateColumns="AddNew" HorizontalAlignment="Left" VerticalAlignment="Top" SelectedItem="{Binding SelectedNames,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<dxg:GridControl.View>
<dxg:TableView ShowTotalSummary="True"/>
</dxg:GridControl.View>
</dxg:GridControl>
</Grid>
</dxdo:LayoutPanel>
<dxdo:LayoutPanel Caption="Panel2" x:Name="abc1">
<TextBox Width="166" Background="White" Height="33" HorizontalAlignment="Right" VerticalAlignment="Bottom" Text="{Binding Path=SelectedCustomer.LastName,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
</dxdo:LayoutPanel>
Bsically I changed the type of SelectedCustomer to one of the collection of items. In the view you can set the binding of your TextBox directly to a property of the SelectedCustomer.
It looks like you forgot to raise the INPC (INotifyPropertyChanged) event for the "LastName" string.
So try this (changed is in the setter below):
public NameModelClass SelectedCustomer
{
get { return _selectedCustomer; }
set
{
if (_selectedCustomer != value)
{
_selectedCustomer = value;
LastName = value.LastName;
OnPropertyChanged("SelectedCustomer");
OnPropertyChanged("LastName"); //<-- new
}
}
}
You have to send out INPCs so that the binding knows to update to the new value. The displayed binding won't "grab" the new value for LastName unles you raise that event.
Have you tried:
SelectedItem="{Binding SelectedNames, Mode=TwoWay}"
After looking at it more, your main Namess Class could do with implementing INotifyPropertyChanged
With each property raising the property changed event when it ahem changes.
Also using an observable collection so when you add and remove items it also raises changes.
That way, the notification change system receives the notify of property changes to change the view accordingly via bindings.

Categories