How to set combo box value in WPF using MVVM architecture - c#

I created a POC in WPF MVVM architecture.In which I used combo box control you can see in the code below.
<ComboBox Name="DeptCombo" Grid.Row="4" Grid.Column="1" ItemsSource="{Binding DepartmentList,Mode=TwoWay}" SelectedItem="{Binding Path=CurrentDepartment,Mode=TwoWay}" DisplayMemberPath="DepartmentName">
</ComboBox>
here CurrentDepartment is a property of Department class.
Everything is fine, I filled that combo , saved that combo value in the database, But the only problem I was facing is, I am not able to set the saved database value in that combo.I don't get any solution regarding that.Please help me.

Add UpdateSourceTrigger
SelectedItem="{Binding Path=CurrentDepartment,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Еhe code should look something like this:
class ViewModel: INotifyPropertyChanged
{
public ObservableCollection<string> Datas { get; set; } = new ObservableCollection<string>()
{
"FF", "AA", "BB"
};
private string currentItem;
public string CurrentItem
{
get => currentItem;
set
{
currentItem = value;
OnPropertyChanged("CurrentItem");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string prop="")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
}
}
Example with Model:
PersonModel.cs:
class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
}
ViewModel.cs:
class ViewModel: INotifyPropertyChanged
{
public ObservableCollection<PersonModel> Datas { get; set; } = new ObservableCollection<PersonModel>()
{
new PersonModel(){Age = 10, Name="Tom"},
new PersonModel(){Age = 10, Name="Mark"},
};
private PersonModel currentItem;
public PersonModel CurrentItem
{
get => currentItem;
set
{
currentItem = value;
OnPropertyChanged("CurrentItem");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string prop="")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
}
}
MainWindow.xaml:
<ComboBox ItemsSource="{Binding Datas}" SelectedItem="{Binding CurrentItem, UpdateSourceTrigger=PropertyChanged}"
Height="100" Width="100">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Age}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

Department Class :
public class Department : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertychanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private int id;
public int Id
{
get { return id; }
set { id = value; OnPropertychanged("Id"); }
}
private string departmentName;
public string DepartmentName
{
get { return departmentName; }
set { departmentName = value; OnPropertychanged("DepartmentName"); }
}
private bool isActive;
public bool IsActive
{
get { return isActive; }
set { isActive = value; OnPropertychanged("IsActive"); }
}
}
View Model :
private ObservableCollection<Department> departmentList;
public ObservableCollection<Department> DepartmentList
{
get { return departmentList; }
set { departmentList = value; OnPropertyChanged("DepartmentList"); }
}
private Department currentDepartment;
public Department CurrentDepartment
{
get { return currentDepartment; }
set { currentDepartment = value; OnPropertyChanged("CurrentDepartment"); }
}
private void DepartmentPop()
{
DepartmentList = new ObservableCollection<Department>
(objDepartmentService.GetAll());
}

Related

Implementing INotifyPropertyChanged in my project Xamarin

so I have a model class that I called "Objets" and I want to creat a ViewModel so that I can track the changes that happen in one of my Model class arguments which is "nbr_objet".
what should I do ?
this what I've done so far and please correct me.
Model Class :
public class Objets
{
public string Designation { get; set; }
public string Description { get; set; }
public float Prix { get; set; }
public int nbr_objet { get; set; }
public Objets(string Designation, string Description, float Prix, int nbr_objet)
{
this.Designation = Designation;
this.Description = Description;
this.Prix = Prix;
this.nbr_objet= nbr_objet;
}
}
ModelViewBase where I have the problem obviously
class ViewModelBase : INotifyPropertyChanged
{
public Objets ObjetVM { get; set; }
public int nbr_objet
{
get { return ObjetVM.nbr_objet; }
set
{
ObjetVM.nbr_objet = value;
OnPropertyChanged(nameof(ObjetVM.nbr_objet));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
And this is my MainPage.xaml.cs where I creat multiple "Objets"
public MenuPage()
{
InitializeComponent();
this.BindingContext = new ViewModelBase();
}
Here is running screenshot.
You can achieve it like following format in your model.
public class MyObjets : INotifyPropertyChanged
{
// public string Designation { get; set; }
// public string Description { get; set; }
// public float Prix { get; set; }
// public int nbr_objet { get; set; }
int _nbr_objet;
public int Nbr_objet
{
get
{
return _nbr_objet;
}
set
{
if (_nbr_objet != value)
{
_nbr_objet = value;
OnPropertyChanged("Nbr_objet");
}
}
}
float _prix;
public float Prix
{
get
{
return _prix;
}
set
{
if (_prix != value)
{
_prix = value;
OnPropertyChanged("Prix");
}
}
}
string _designation;
public string Designation
{
get
{
return _designation;
}
set
{
if (_designation != value)
{
_designation = value;
OnPropertyChanged("Designation");
}
}
}
string _description;
public string Description
{
get
{
return _description;
}
set
{
if (_description != value)
{
_description = value;
OnPropertyChanged("Description");
}
}
}
public MyObjets(string Designation, string Description, float Prix, int nbr_objet)
{
this._designation = Designation;
this._description = Description;
this._prix = Prix;
this._nbr_objet = nbr_objet;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Then Here is Layout.
<StackLayout>
<!-- Place new controls here -->
<Label Text="{Binding Designation}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Label Text="{Binding Description}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Label Text="{Binding Prix}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Label Text="{Binding Nbr_objet}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
Here is layout backend code.
public MainPage()
{
InitializeComponent();
BindingContext = new MyObjets("xxxx","cccc",1.22f,11);
}
Here is my demo about MVVM with Listview, you can refer to it as well.
https://github.com/851265601/MVVMListview
If the reply is helpful, please do not forget to mark it as answer.
======================Update========================
You want to achieve the result like following GIF?
Here is your model
public class MyObjets
{
public string Designation { get; set; }
public string Description { get; set; }
public float Prix { get; set; }
public int nbr_objet { get; set; }
public MyObjets(string Designation, string Description, float Prix, int nbr_objet)
{
this.Designation = Designation;
this.Description = Description;
this.Prix = Prix;
this.nbr_objet = nbr_objet;
}
}
Here is ViewModelBase
public class ViewModelBase: INotifyPropertyChanged
{
public ViewModelBase()
{
ObjetVM = new MyObjets("ccc","xxx",1.2f,123);
}
public MyObjets ObjetVM { get; set; }
public int nbr_objet
{
get { return ObjetVM.nbr_objet; }
set
{
ObjetVM.nbr_objet = value;
OnPropertyChanged(nameof(ObjetVM.nbr_objet));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
Here layout forground code.
<StackLayout>
<Label Text="{Binding nbr_objet}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Button Text="change the value" Clicked="Button_Clicked"></Button>
</StackLayout>
here is layout background code.
public partial class MainPage : ContentPage
{
ViewModelBase viewModelBase;
public MainPage()
{
InitializeComponent();
viewModelBase = new ViewModelBase();
BindingContext = viewModelBase;
}
private void Button_Clicked(object sender, EventArgs e)
{
viewModelBase.nbr_objet = 111;
}
}
You need to implement INotifyPropertyChanged on any object you want to track changes on. Right now you are only tracking changes on the viewmodel, so you also need to add INotifyPropertyChanged on the Objets class, too, as well as each property within the class with the getters/setters with OnPropertyChanged like you did in the viewmodel.
public class Objets: INotifyPropertyChanged
When you change the property "nbr_objet" you raise that your property inside the ObjetVM has changed, but this is not your bindingContext - your bindingContext is the ViewModelBase.
So rather rewrite it:
private int nbr_object;
public int Nbr_objet_property
{
get { return nbr_objet; }
set
{
nbr_objet = value;
OnPropertyChanged(nameof(Nbr_objet_property));
}
}
And then everytime you cahnge "Nbr_objet_property" it should update whatever you binded it to.
Also, "ObjetVM" is no a viewModel since it does not implement the INotifyPropertyChanged logic.
Hope it makes sense? :)

Deleting and Editing an item in a listview with Viewmodel and without using the codebehind

In the shown code i need to know the coding to be replaced in place of question mark in the code. I need to delete,edit and update the item in the list view without writing any code in code behind. I only want to do these operations by bindin view with view model through Icommand
This a class in my model Playlist.cs
namespace MvvmDemo.Models
{
public class Playlist
{
public string Title { get; set; }
}
}
This is a class in my viewmodel PlaylistsViewModel.cs
namespace MvvmDemo.ViewModels
{
public class PlaylistsViewModel
{
public ObservableCollection Playlists { get; private set; } = new ObservableCollection();
public ICommand AddPlaylistCommand { get; private set; }
public ICommand DeletePlaylistCommand { get; private set; }
public ICommand EditPlaylistCommand { get; private set; }
public PlaylistsViewModel()
{
AddPlaylistCommand = new Command(AddPlaylist);
DeletePlaylistCommand = new Command(DeletePlaylist);
}
public void AddPlaylist()
{
var newPlaylist = "Playlist " + (Playlists.Count + 1);
Playlists.Add(new Playlist { Title = newPlaylist });
}
public void DeletePlaylist()
{
????????????????
}
public void EditPlaylist()
{
????????????????
}
}
}
you have to make the command is parameterised and pass binding data through the parameter.
and from that data you can get the index value of selected.using that remove the item from the list.
Playlists.RemoveAt("INDEX_NUMBER");
To update it in the view use "INotifyProperty" also
If you want to delete and edit item in ListView, firstly, you should need to use ICommand, then you could need to use INotifyPropertyChanged to implement Inotify.
I do one sample that you can take a look. Choosing one Item and long press with the left mouse button, you will see two ways, delete Item and Edit Item action.
<ContentPage.Content>
<StackLayout>
<ListView
x:Name="mylistview"
ItemsSource="{Binding lists}"
SelectedItem="{Binding selecteditem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem
Command="{Binding BindingContext.DeletePlaylistCommand, Source={x:Reference Name=mylistview}}"
IsDestructive="true"
Text="Delete Item" />
<MenuItem
Command="{Binding BindingContext.EditPlaylistCommand, Source={x:Reference Name=mylistview}}"
IsDestructive="true"
Text="Edit Item" />
</ViewCell.ContextActions>
<StackLayout Padding="15,0">
<Label Text="{Binding Title}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Page19 : ContentPage, INotifyPropertyChanged
{
public ObservableCollection<Playlist> lists { get; set; }
//public RelayCommand1 AddPlaylistCommand { get; set; }
public RelayCommand DeletePlaylistCommand { get; set; }
public RelayCommand EditPlaylistCommand { get; set; }
private Playlist _selecteditem;
public Playlist selecteditem
{
get { return _selecteditem; }
set
{
_selecteditem = value;
RaisePropertyChanged("selecteditem");
}
}
public Page19 ()
{
InitializeComponent ();
lists = new ObservableCollection<Playlist>()
{
new Playlist(){Id=1,Title="list 1"},
new Playlist(){Id=2, Title="list 2"},
new Playlist(){Id=3,Title="list 3"},
new Playlist(){Id=4,Title="list 4"},
new Playlist(){Id=5,Title="list 5"},
new Playlist(){Id=6,Title="list 6"},
};
DeletePlaylistCommand = new RelayCommand(DeletePlaylist);
EditPlaylistCommand = new RelayCommand(EditPlaylist);
selecteditem = lists[0];
this.BindingContext = this;
}
public void AddPlaylist()
{
}
public void DeletePlaylist()
{
Playlist item = selecteditem;
lists.Remove(item);
}
public void EditPlaylist()
{
Playlist item = selecteditem;
int id = item.Id;
foreach(Playlist playl in lists.Where(a=>a.Id==id))
{
playl.Title = "chenge title";
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class Playlist: INotifyPropertyChanged
{
private int _Id;
public int Id
{
get { return _Id; }
set
{
_Id = value;
RaisePropertyChanged("Id");
}
}
private string _Title;
public string Title
{
get { return _Title;}
set
{
_Title = value;
RaisePropertyChanged("Title");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Here is the RelayCommd:
public class RelayCommand : ICommand
{
readonly Action _execute;
public RelayCommand(Action execute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_execute();
}
}
You can use observablecollection. It will reflect add,remove operation of item to the listview. And for editing item you have to raise property changed for all property you are editing.To simplify that property changed you can implement property changed event to your Playlist model class.
Like
public void DeletePlaylist()
{
Playlists.Remove(newPlaylist);
}
public void EditPlaylist()
{
newPlaylist.Title="Refreshed Playlist"
}
public class Playlist:INotifyPropertyChanged
{
private string title;
public string Title
{
get{return title;}
set{title=value;
NotifyPropertyChanged();}
}
}

Model and ViewModel Consept MVVM WPF

I want to read some data from database and do some process on them and then view them in the view.
I read a lot about MVVM and now I am confused.
Imaging I read a person entity from database with Name attribute.
please make a small code and show me how should I make my model and ViewModel.
I guess it we will be something like this :
public class PersonModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string Name;
public string name
{
get
{
return Name;
}
set
{
Name = value;
onpropertychanged("name");
}
}
public PersonModel( string s)
{
name = s;
}
public void onpropertychanged(string PName)
{
if (PropertyChanged !=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(PName));
}
}
}
public class PersonViewModel
{
public ObservableCollection <PersonModel> list { get; set; }
public PersonViewModel()
{
list = new ObservableCollection<model>();
list.Add(new model("abc"));
list.Add(new model("def"));
}
public void change()
{
list[1].name = "changed";
}
}
public class ViewModelBase
{
public PersonViewModel vperson { get; set; }
public ViewModelBase()
{
vperson = new PersonViewModel();
vperson.change();
}
}
Edite : Where should database connections be?
Edite :
<Grid>
<TextBox Text="{Binding vperson.list[1].name}" />
</Grid>
</Window>
I edited your classes and is working
public class PersonModel : INotifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set
{
if (_name == value) return;
_name = value;
OnPropertyChanged();
}
}
public PersonModel(string name)
{
_name = name;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class PersonViewModel
{
public ObservableCollection<PersonModel> Items { get; set; }
public PersonViewModel()
{
Items = new ObservableCollection<PersonModel> { new PersonModel("abc"), new PersonModel("def") };
}
public void Change()
{
Items[1].Name = "changed";
}
}
public class ViewModelBase
{
public PersonViewModel PersonViewModel { get; set; }
public ViewModelBase()
{
PersonViewModel = new PersonViewModel();
PersonViewModel.Change();
}
}
//Use the dataContext in this way, will help you with the strong type
xmlns:viewModels="clr-namespace:WpfApp1.ViewModels"
<Window.DataContext>
<viewModels:ViewModelBase />
</Window.DataContext>
<Grid>
<TextBox Text="{Binding PersonViewModel.Items[1].Name}" />
</Grid>

WPF Make ComboBox selection trigger multiple properties change

I have two classes that have identical Name and Position properties. A ComboBox in a DataGrid has a list of StaffMember class taken from a database. It displays the name only but upon selection both Name and Position properties should change in the DataGrid bound to ObservableCollection of another class - Person.
So far I'm using the SelectionChanged event of the combobox to browse the VisualTree, access parent DataContext and change two properties at a time.
Is there a different approach to it?
Update. Here's an illustrating picture:
I get the Name and Position from a third party service and display the name in the combobox. As user selects a name the UI should update both Name and Position properties in the table. The table also has Age and many other columns/properties in real world. That is why there are two classes: a name/position list from a database to select from and a class which is the ItemSource of the table. I also have to deal with cases when people have the same name but different positions. Hope this explains the question better.
public class StaffMember : NotifyObject
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; OnPropertyChanged("Name"); }
}
private string _position;
public string Position
{
get { return _position; }
set { _position = value; OnPropertyChanged("Position"); }
}
}
public class Person : NotifyObject
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; OnPropertyChanged("Name"); }
}
private string _position;
public string Position
{
get { return _position; }
set { _position = value; OnPropertyChanged("Position"); }
}
public double Age { get; set; }
}
ViewModel:
public class ViewModel : NotifyObject
{
public ObservableCollection<Person> SelectedPeople { get; set; }
public List<StaffMember> Staff { get; set; }
public ViewModel()
{
Staff = new List<StaffMember>
{
new StaffMember { Name = "Sigmund Freud", Position = "Psychologist"},
new StaffMember { Name = "Louis Armstrong", Position = "Musician"},
new StaffMember { Name = "John Doe", Position = "Superviser"},
new StaffMember { Name = "John Doe", Position = "Manager"},
};
SelectedPeople = new ObservableCollection<Person> {
new Person { Name = "Sigmund Freud", Position = "123", Age= 161 },
new Person(),
new Person() };
}
}
public abstract class NotifyObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
public void RaiseProperychanged(string propertyName)
{
OnPropertyChanged(propertyName);
}
}
XAML:
<Grid>
<DataGrid ItemsSource="{Binding SelectedPeople}"
AutoGenerateColumns="False"
CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="ComboBoxSelect" ItemsSource="{Binding ElementName=TheMainWindow, Path=DataContext.Staff}"
SelectedValue="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=DataContext.Name, Mode=TwoWay}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectionChanged="ComboBoxSelect_SelectionChanged"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Position" Binding="{Binding Position, Mode=TwoWay}"/>
<DataGridTextColumn Header="Age" Binding="{Binding Age}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
Code-Behind:
private void ComboBoxSelect_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var comboBox = sender as ComboBox;
var parent = sender as DependencyObject;
while (!(parent is DataGridCell))
{
parent = VisualTreeHelper.GetParent(parent);
if (parent is null) return;
}
var cell = parent as DataGridCell;
if (cell == null) return;
var person = cell.DataContext as Person;
if (person == null) return;
person.Position = ((StaffMember)comboBox.SelectedItem).Position.ToString();
}
It is not a good idea to mix MVVM and code-behind.
You have a duplication of data in Person and StaffMember class.
What about idea of having StaffMember property in Person class?
public class StaffMember : NotifyObject
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; OnPropertyChanged("Name"); }
}
private string _position;
public string Position
{
get { return _position; }
set { _position = value; OnPropertyChanged("Position"); }
}
}
public class Person : NotifyObject
{
private string _staffMember;
public string StaffMember
{
get { return _staffMember; }
set { _staffMember = value; OnPropertyChanged("StaffMember"); }
}
public double Age { get; set; }
}

C# ListBox/ListView not showing elements - Metro UI

I am using a ListBox in my Metro UI media player, but the ListBox doesn't show any text when I run it. I don't have any errors or so, but there is no text. I have also tried to use a ListView and not a ListBox, but the result was the same. What can I do ?
I am using the next code for the ListBox on the XAML part of the page
<ListBox x:Name="ItemListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding PathToFile}"
FontSize="24" Margin="5,0,0,0" TextWrapping="Wrap" />
<TextBlock Text="{Binding HasVideo}"
FontSize="16" Margin="15,0,0,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and the next code on the page C# code :
public static ListBox ListBoxIstance = null;
public MainPage()
{
InitializeComponent();
ListBoxIstance = ItemListBox;
ItemListBox.ItemsSource = Data_Repository.MediaData.MediaList;
ItemListBox.DataContext = Data_Repository.MediaData.MediaList;
}
where MediaList is a list declared as it follows
public static List<MediaFile> MediaList = new List<MediaFile>();
and MediaFile is a class
public class MediaFile
{
public TimeSpan Duration = TimeSpan.Zero;
public bool HasAudio = false;
public bool HasVideo = false;
public String PathToFile = null;
public MediaFile(string _pathToFile)
{
PathToFile = _pathToFile;
}
}
I am using the next code to update the MediaList and the ItemListBox
foreach (var pathToFile in files)
{
MediaList.Add(new MediaFile(pathToFile.Path));
MainPage.ListBoxIstance.UpdateLayout();
}
EDIT : After some suggestions :
That's how the MediaFile class looks like :
public class MediaFile : INotifyPropertyChanged
{
private bool _hasAudio;
public bool HasAudio
{
get { return _hasAudio; }
set
{
_hasAudio = value;
OnPropertyChanged("HasAudio");
}
}
private bool _hasVideo;
public bool HasVideo
{
get { return _hasVideo; }
set
{
_hasVideo = value;
OnPropertyChanged("HasVideo");
}
}
private String _pathToFile;
public String PathToFile
{
get { return _pathToFile; }
set
{
_pathToFile = value;
OnPropertyChanged("PathToFile");
}
}
public MediaFile(string pathToFile)
{
PathToFile = pathToFile;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
and I am using
public static ObservableCollection<MediaFile> MediaList = new ObservableCollection<MediaFile>();
You can't bind to public fields in your item class. Turn the class members into public properties:
public class MediaFile
{
public TimeSpan Duration { get; set; }
public bool HasAudio { get; set; }
public bool HasVideo { get; set; }
public String PathToFile { get; set; }
public MediaFile(string _pathToFile)
{
PathToFile = _pathToFile;
}
}
Then use an ObservableCollection instead of a List. That would automatically update the ItemsSource binding when items are added or removed. No need to call UpdateLayout.
public ObservableCollection<MediaFile> MediaList =
new ObservableCollection<MediaFile>();
If you also want to update the UI when any of the property values changes after a MediaFile object has been added to the list, you also have to implement the INotifyPropertyChanged interface:
public class MediaFile : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private bool hasVideo
public bool HasVideo
{
get { return hasVideo; }
set
{
hasVideo = value;
OnPropertyChanged("HasVideo");
}
}
// other properties
}
You can only bind with properties and not with fields. Change fields to properties.
public bool HasVideo {get;set;}
public String PathToFile {get;set;}

Categories

Resources