Get CheckBox Content with Databinding in C# ListView Checkbox - c#

Coming from python and need to translate some old app i made to C#.
I have a ListView with Checkboxes.
XAML
<ListView Name ="spored" SelectionMode="Multiple" HorizontalAlignment="Left" VerticalAlignment="Stretch" Margin="10,10,10,10" Width="750">
<ListView.View>
<GridView>
<GridViewColumn Header="data">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding CheckedShow, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
In code i have everything i need to populate this Listview and it works great.
public class Show
{
public bool CheckedShow { get; set; } //listview checkbox
public string Name { get; set; } //listview checkbox content
}
public List<Show> showList = new List<Show>();
private void ShowSpored_Click(object sender, RoutedEventArgs e)
{
//here i have some foreeach loop that populates showList
foreach(...)
{
.
.
.
showList.Add(new Show() { CheckedShow = false, Name = infoKey });
}
//after loop i populate Listview with
spored.ItemsSource = showList;
}
Now what i need to achieve and have NO idea how is the following.
While list is populated i need to run some code on checked Content.
I figured i need to do this with INotifyPropertyChanged.PropertyChanged Event
But for the noob that i am i can't seem to manage to get Checked Content...
public class Content : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
.
.
.
}
Help please!!!

Change
showList.Add(new Show() { CheckedShow = false, Name = infoKey });
to
var item = new Show() { CheckedShow = false, Name = infoKey };
showList.Add(item);
if(item.CheckedShow) ... // run some code

Figured it out.
Had to add this to cs:
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
public event PropertyChangedEventHandler PropertyChanged;
And then make a class like this:
public class Show: INotifyPropertyChanged
{
private bool _IsChecked;
private string _Name;
public bool IsChecked
{
get { return _IsChecked; }
set
{
if (_IsChecked != value)
{
_IsChecked = value;
OnPropertyChanged("IsChecked");
if (_IsChecked == true)
{
Console.WriteLine(_Name + "do some shit");
}
else
{ Console.WriteLine("do some other shit"); }
}
}
}
public string Name
{
get
{
return _Name;
}
set
{
if (_Name != value)
{
_Name = value;
}
}
}

Related

Binding checkbox ischecked inside listbox(WPF)

I'm trying to bind checkbox ischecked value. but whenever I click multiple checkbox, only last item is get selected.
This is my xaml.
<ListBox x:Name="EntryBox" ItemsSource="{Binding SourceCollection}"
SelectedItem="{Binding SelectedCheckbox}" SelectionMode="Multiple"
Grid.Column="0" Grid.Row="0" >
<ListBox.ItemTemplate>
<DataTemplate>
<ListBoxItem IsSelected="{Binding Selected}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Selected}"/>
</StackPanel>
</ListBoxItem>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My viewmodel
public class MytViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<Item> _socketEntryCollection;
public MyViewModel()
{
_socketEntryCollection = new ObservableCollection<Item>();
}
private ListCollectionView _sourceCollection;
public ListCollectionView SourceCollection
{
get { return _sourceCollection; }
set
{
_sourceCollection = value;
NotifyPropertyChanged(nameof(SourceCollection));
}
}
private Item _selectedCheckbox;
public Item SelectedCheckbox
{
get
{
return _selectedCheckbox;
}
set
{
_selectedCheckbox = value;
NotifyPropertyChanged(nameof(SelectedCheckbox));
}
}
public class Item : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool _selected;
public Item()
{
_selected = false;
}
public bool Selected
{
get { return _selected; }
set
{
if(_selected != value)
{
_selected = value;
NotifyPropertyChanged(nameof(Selected));
}
}
}
private void NotifyPropertyChanged(string Obj)
{
if (PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(Obj));
}
}
In my code behind,
private MyViewModel _BVM;
public BulkTest()
{
InitializeComponent();
_BVM = new MyViewModel();
}
foreach (MyViewModel.Item i in _BVM.SourceCollection)
{
if (i.Selected)
{
}
}
When I try to retrieve selected items, it only gives me only the last item I checked even though I checked multiple.
I would like to get every item that I checked.
How can I do that?

Binding constant Collection to ComboBox & SelectedItem to TextBox

I'm new to MVVM in WPF and I have the following problem.
What I try to have is two ComboBoxes, each binding to the same ObservableCollection<TwoProperties> DList property as ItemsSource and with synchronized SelectedItem, so I wrote this in my XAML
<ComboBox ItemsSource="{Binding DList}" DisplayMemberPath="Property1" SelectedItem="{Binding SelectedD}" />
<ComboBox ItemsSource="{Binding DList}" DisplayMemberPath="Property2" SelectedItem="{Binding SelectedD}" />
with this viewmodel
public class ViewModel : INotifyPropertyChanged
{
private ObservableCollection<TwoProperties> _dList =
new ObservableCollection<TwoProperties> {
new TwoProperties(1,"one"),
new TwoProperties(2,"two")
};
public ObservableCollection<TwoProperties> DList
{
get { return _dList; }
set { _dList = value; OnPropertyChanged("DList"); }
}
private TwoProperties _selectedD;
public TwoProperties SelectedD
{
get { return _selectedD; }
set { _selectedD = value; OnPropertyChanged("SelectedD"); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
where
public class TwoProperties
{
public double Property1 { get; set; }
public string Property2 { get; set; }
public TwoProperties (double p1, string p2)
{
Property1 = p1;
Property2 = p2;
}
}
I would also like to have two TextBoxes that display the properties of the currently SelectedItem of the synchronized ComboBoxes. The properties Property1 and Property2 of SelectedD should be editable, however the ObservableCollection<TwoProperties> _dList should remain constant/readonly and not change its values.
<TextBox Text="{Binding SelectedD.Property1}" />
<TextBox Text="{Binding SelectedD.Property2}" />
But when I edit the TextBoxes and therefore SelectedD, also _dList changes its values, which is not what I want.
I hope I could explain my problem. I'm sure I'm missing something simple here.
This could be implemented easily by changing the binding mode for the TextBoxes into one way as following:
<TextBox Text="{Binding SelectedD.Property1,Mode=OneWay}" />
<TextBox Text="{Binding SelectedD.Property2,Mode=OneWay}" />
Thus when you change the textBox value, the changes would not be reflected back to the Observable collection objects.
Note that you can get rid of magical strings in your view model OnPropertyChanged by modifying the method as following:
private void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
And then you can call it inside the setter of any property inside the view model without passing the name of the property as following:
private TwoProperties _selectedD;
public TwoProperties SelectedD
{
get { return _selectedD; }
set { _selectedD = value; OnPropertyChanged(); }
}
Edit 2:
Update my binding and view model to get the edited values inside the view model
View model updates:
private double? editPropertyOne;
public double? EditPropertyOne
{
get { return editPropertyOne; }
set
{
editPropertyOne = value;
OnPropertyChanged();
}
}
private string editPropertyTwo;
public string EditPropertyTwo
{
get { return editPropertyTwo; }
set
{
editPropertyTwo = value;
OnPropertyChanged();
}
}
private TwoProperties _selectedD;
public TwoProperties SelectedD
{
get { return _selectedD; }
set
{
_selectedD = value; OnPropertyChanged();
if (_selectedD != null)
{
EditPropertyOne = _selectedD.Property1;
EditPropertyTwo = _selectedD.Property2;
}
}
}
Xaml changes:
<TextBox Text="{Binding EditPropertyOne}" />
<TextBox Text="{Binding EditPropertyTwo}" />

textbox input to get / set viewmodel

I'm sure this has already been asked, but I'm still new to MVVM and WPF, and not too sure what I should be searching for.
I have a viewmodel which includes items in a Model, as well as some additional temporary data items which will all be passed to a process.start(). I have a stackpanel of textbox, and want to allow the user to type in a "ModelName", and if existing, The ViewModel will get and set "TemplateName" associated with the ModelName.
I'm a bit lost on how to implement this. Do I need to create a completely separate ViewModel, which then goes and extracts data from ModelViewModel? Do I just write some code under ModelName's set, where it can validate, query, and set TemplateName?
Model:
public partial class Model
{
public string ModelName { get; set; }
public virtual Template Template { get; set; }
and ViewModel, which takes the Model, and some temporary data:
public class LauncherViewModel:ViewModelBase
{
public LauncherViewModel()
{
_ESTContext = new ESTContext();
Models = new ObservableCollection<Model>(_ESTContext.Models);
}
private ESTContext _ESTContext;
private string _modelname;
private string _serialno;
private string _sonumber;
private string _templatename;
private string _outputname;
private Model _selectedmodel;
public ObservableCollection<Model> Models { get; set; }
public string ModelName
{
get { return _modelname; }
set
{
if (!string.Equals(_modelname, value))
{
_modelname = value;
};
}
}
public string TemplateName { get { return _templatename; }}
public string SerialNo { get { return _serialno; } }
public string SONumber { get { return _sonumber; } }
public string OutputName { get { return _outputname; } }
public Model SelectedModel
{
get { return _selectedmodel; }
set
{
if (_selectedmodel != value)
{
_selectedmodel = value;
}
}
}
}
My View:
<DockPanel>
<StackPanel Margin="0,78,0,68" Width="233" DataContext="{Binding Models}">
<ComboBox IsEditable="True" Text="{Binding ModelName}" SelectedItem="{Binding SelectedModel}"/>
<TextBox Height="23" TextWrapping="Wrap" Text="{Binding SONumber}"/>
<TextBox Height="23" TextWrapping="Wrap" Text="{Binding SerialNumber}"/>
<Button Content="Button"/>
</StackPanel>
</DockPanel>
For your gui to update you must implement INotifyPropertyChanged and a call to it on all your bound properties.
// basic base class for your models, you a
public class ModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator] // remove if you are not using R#
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
// your model
public class Model : ModelBase
{
private string modelName;
private Template template;
public string ModelName
{
get { return modelName; }
set
{
if (value == modelName) return;
modelName = value;
OnPropertyChanged();
}
}
public virtual Template Template
{
get { return template; }
set
{
if (Equals(value, template)) return;
template = value;
OnPropertyChanged();
}
}
}
View:
<DockPanel>
<StackPanel Margin="0,78,0,68" Width="233">
<ComboBox IsEditable="True" Text="{Binding ModelName, Mode='TwoWay'}" SelectedItem="{Binding SelectedModel}" ItemsSource="{Binding Models}"/>
<TextBox Height="23" TextWrapping="Wrap" Text="{Binding SONumber Mode='TwoWay'}"/>
<TextBox Height="23" TextWrapping="Wrap" Text="{Binding SerialNumber Mode='TwoWay'}"/>
<Button Content="Button"/>
</StackPanel>
Note the Mode='TwoWay' this makes the GUI change the values in your viewmodel, rather than just display them. So you need to set that on everything that's supposed to be editable as above. The default behaviour of WPF is that when a control looses focus it will update the bound property, if you set UpdateSourceTrigger='PropertyChanged' the property will be updated each time ie a letter is entered in a text box. I'll leave that part to you, but you will have to do it in your vm! At minimum the properties SONumber,SerialNumber and Models(if it's ref. changes).
VM: I assume you use galasoft here
public class LauncherViewModel : ViewModelBase
{
private ESTContext _ESTContext;
private string _templatename;
private string _modelname;
private string serialNumber;
private string _outputname;
private string modelName;
private ObservableCollection<Model> models;
private Model selectedModel;
private string soNumber;
public LauncherViewModel()
{
// dangerous ;)
_ESTContext = new ESTContext();
Models = new ObservableCollection<Model>(_ESTContext.Models);
}
public ObservableCollection<Model> Models
{
get { return models; }
set
{
if (Equals(value, models)) return;
models = value;
RaisePropertyChanged();
}
}
public string ModelName
{
get { return modelName; }
set
{
if (value == modelName) return;
modelName = value;
RaisePropertyChanged();
}
}
public string TemplateName { get { return _templatename; }}
public string SerialNumber // Note you spelled this wrong in your xaml. SONumber
{
get { return serialNumber; }
set
{
if (value == serialNumber) return;
serialNumber = value;
RaisePropertyChanged();
}
}
public string SONumber
{
get { return soNumber; }
set
{
if (value == soNumber) return;
soNumber = value;
RaisePropertyChanged();
}
}
public string OutputName { get { return _outputname; } }
public Model SelectedModel
{
get { return selectedModel; }
set
{
if (Equals(value, selectedModel)) return;
selectedModel = value;
RaisePropertyChanged();
}
}
}
A cool litle thing if you are using galasoft or sim together with R#.
public class YourViewModelBase : ViewModelBase
{
[NotifyPropertyChangedInvocator] // alt + enter = convert auto property to prop
// with backing field and change notification :)
override protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
base.RaisePropertyChanged(propertyName);
}
// .. :)
}
Cheers,
Stian
If I havent misunderstood your question , Bind Models to ItemsSource of ComboBox instead of Binding it to DataContext of StackPanel
Remove DataContext binding
<StackPanel Margin="0,78,0,68" Width="233" >
Bind Itemssource of ComboBox to Models and you will also have to specify DisplayMemberPath to the property of Model that you want to display in ComboBox.
<ComboBox IsEditable="True" ItemsSource="{Binding Models}" Text="{Binding ModelName}" SelectedItem="{Binding SelectedModel}"/>
And I am assuming you are setting DataContext of window to instance of LauncherViewModel class.
You need to raise the property changed event on properties you bind to i.e.:
private string _ModelName;
public string ModelName
{
get { return _ModelName; }
set
{
if (_ModelName != value)
{
_ModelName = value;
RaisePropertyChanged("ModelName");
}
}
}
In your base view model you need something like this (make sure you implement INotifyPropertyChanged):
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
In the constructor or loaded event of your view add this:
DataContext = new LauncherViewModel();

Add additional control to ObervableCollection

I'm really new to WPF so apologies in adavnced if this is an obvious question. I have a simple Checkbox in XAML as
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding Selections}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid >
<CheckBox IsChecked="{Binding IsChecked}"
Content="{Binding Path=Item.SelectionName}" />
</Grid >
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Simplified code behind to allow bindings and INotifyPropertyChanged is:
public ObservableCollection<CheckedListItem<Selection>> Selections { get; set; }
public class Selection
{
public String SelectionName { get; set; }
}
Selections = new ObservableCollection<CheckedListItem<Selection>>();
Selections.Add(new CheckedListItem<Selection>(new Selection()
{ SelectionName = "SomeName" }, isChecked: true));
public class CheckedListItem<T> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool isChecked;
private T item;
public CheckedListItem()
{ }
public CheckedListItem(T item, bool isChecked = false)
{
this.item = item;
this.isChecked = isChecked;
}
public T Item
{
get { return item; }
set
{
item = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Item"));
}
}
public bool IsChecked
{
get { return isChecked; }
set
{
isChecked = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
}
}
}
I now need to add an additional TextBox associated with each Checkbox, so in XAML I have
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding Selections}" Margin="12,22,12,94">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid >
<CheckBox IsChecked="{Binding IsChecked}"
Content="{Binding Path=Item.SelectionName}" />
<<TextBox />
</Grid >
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm a bit stumped how to include this as part of the ObservableCollection and set it up the binding on both the CheckBox and associated TextBox? Both are being added together using Selections.Add(new CheckedListItem<Selection>(new Selection()
{ SelectionName = "SomeName" }, isChecked: true)); which is causing me some confusion.
EDIT: Added full code
public partial class SelectionSettingWindow : Window
{
public ObservableCollection<CheckedListItem<Selection>> Selections { get; set; }
public class Selection
{
public String SelectionName { get; set; }
public string SelectionTextField { get; set; }
}
public SelectionSettingWindow()
{
InitializeComponent();
Selections = new ObservableCollection<CheckedListItem<Selection>>();
string fg = #"Item1,true,TExtbox1text:Item2,true,TExtbox2text:Item3,false,TExtbox3text"; //Test String
string[] splitSelections = fg.Split(':');
foreach (string item in splitSelections)
{
string[] spSelectionSetting = item.Split(',');
bool bchecked = bool.Parse(spSelectionSetting[1].ToString());
string tbText = spSelectionSetting[2].ToString();
Selections.Add(new CheckedListItem<Selection>(new Selection()
{ SelectionName = spSelectionSetting[0].ToString(),
SelectionTextField = bText }, isChecked: bchecked));
}
DataContext = this;
}
public class CheckedListItem<T> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool isChecked;
private T item;
private string textField;
public CheckedListItem()
{ }
public CheckedListItem(T item, bool isChecked = false)
{
this.item = item;
this.isChecked = isChecked;
}
public T Item
{
get { return item; }
set
{
item = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Item"));
}
}
public bool IsChecked
{
get { return isChecked; }
set
{
isChecked = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
}
}
public string TextField
{
get { return textField; }
set
{
textField = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("TextField"));
}
}
}
}
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding Selections}" Margin="12,22,12,94">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}"
Content="{Binding Path=Item.SelectionName}" />
<TextBox Text="{Binding Item.SelectionTextField, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
replace SelectionTextField above with whatever the field is that needs to be edited using the textbox on your Selection class.
Note that I changed the <Grid> to a <StackPanel> So they wouldn't appear on top of eachother and changed the bindings to TwoWay so the changes are reflected in the model.
Make sure your Selection class implements INotifyPropertyChanged (ObservableCollection updates the UI when things get added to/removed from the collection, it doesn't know anything about notifying when it's content's properties change so they need to do that on their own)
Implementing INotifyPropertyChanged on many classes can be cumbersome. I find implementing a base class useful for this. I've got this along with an extra reflection helper for raise property changed available here and a snippet I've made available. It's silverlight but it should work fine for WPF. Using the code I've provided via download you can simply type proprpc and hit tab and visual studio will stub in a property that notifies on change. Some explanation is in one of my old blog posts here and gives credit for where I based the code and snippet from.

ObservableCollection not updating View

I am just starting with MVVM and have hit a hurdle that I hope someone can help me with. I am trying to create a simple View with 2 listboxes. A selection from the first listbox will populate the second list box. I have a class created that stores the information I want to bind to.
MyObject Class (Observable Object is just a base class that implements INotifyPopertyChanged)
public class MyObject : ObservableObject
{
String _name = String.Empty;
ObservableCollection<MyObject> _subcategories;
public ObservableCollection<MyObject> SubCategories
{
get { return _subcategories; }
set
{
_subcategories = value;
RaisePropertyChanged("SubCategories");
}
}
public String Name
{
get { return _name; }
set
{
_name = value;
RaisePropertyChanged("Name");
}
}
public MyObject()
{
_subcategories = new ObservableCollection<EMSMenuItem>();
}
}
In my viewmodel I have two ObservableCollections created
public ObservableCollection<EMSMenuItem> Level1MenuItems { get; set; }
public ObservableCollection<EMSMenuItem> Level2MenuItems { get; set; }
In my constructor of the ViewModel I have:
this.Level1MenuItems = new ObservableCollection<EMSMenuItem>();
this.Level2MenuItems = new ObservableCollection<EMSMenuItem>();
this.Level1MenuItems = LoadEMSMenuItems("Sample.Xml");
That works fine for the Level1 items and they correctly show in the View. However I have a command that gets called when the user clicks an item in the listbox, which has the following:
Level2MenuItems = ClickedItem.SubCategories;
For some reason this does not update the UI of the second listbox. If I put a breakpoint at this location I can see that Level2MenuItems has the correct information stored in it. If I write a foreach loop and add them individually to the Level2MenuItems collection then it does display correctly.
Also as a test I added the following to the constructor:
Level2MenuItems = Level1MenuItems[0].SubCategories;
And that updated correctly.
So why would the code work as expected in the constructor, or when looping through, but not when a user clicks on an item in the listbox?
You need to raise the change notification on the Level2MenuItems property.
Instead of having
public ObservableCollection<EMSMenuItem> Level2MenuItems { get; set; }
you need
private ObservableCollection<EMSMenuItem> _level2MenuItems;
public ObservableCollection<EMSMenuItem> Level2MenuItems
{
get { return _level2MenuItems; }
set
{
_level2MenuItems = value;
RaisePropertyChanged(nameof(Level2MenuItems));
}
}
The reason the former works in the constructor is that the Binding has not taken place yet. However since you are changing the reference via a command execute which happens after the binding you need to tell view that it changed
You need to make your poco class within the ObservableCollection implement INotifyPropertyChanged.
Example:
<viewModels:LocationsViewModel x:Key="viewModel" />
.
.
.
<ListView
DataContext="{StaticResource viewModel}"
ItemsSource="{Binding Locations}"
IsItemClickEnabled="True"
ItemClick="GroupSection_ItemClick"
ContinuumNavigationTransitionInfo.ExitElementContainer="True">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Margin="0,0,10,0" Style="{ThemeResource ListViewItemTextBlockStyle}" />
<TextBlock Text="{Binding Latitude, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{ThemeResource ListViewItemTextBlockStyle}" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Longitude, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{ThemeResource ListViewItemTextBlockStyle}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public class LocationViewModel : BaseViewModel
{
ObservableCollection<Location> _locations = new ObservableCollection<Location>();
public ObservableCollection<Location> Locations
{
get
{
return _locations;
}
set
{
if (_locations != value)
{
_locations = value;
OnNotifyPropertyChanged();
}
}
}
}
public class Location : BaseViewModel
{
int _locationId = 0;
public int LocationId
{
get
{
return _locationId;
}
set
{
if (_locationId != value)
{
_locationId = value;
OnNotifyPropertyChanged();
}
}
}
string _name = null;
public string Name
{
get
{
return _name;
}
set
{
if (_name != value)
{
_name = value;
OnNotifyPropertyChanged();
}
}
}
float _latitude = 0;
public float Latitude
{
get
{
return _latitude;
}
set
{
if (_latitude != value)
{
_latitude = value;
OnNotifyPropertyChanged();
}
}
}
float _longitude = 0;
public float Longitude
{
get
{
return _longitude;
}
set
{
if (_longitude != value)
{
_longitude = value;
OnNotifyPropertyChanged();
}
}
}
}
public class BaseViewModel : INotifyPropertyChanged
{
#region Events
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected void OnNotifyPropertyChanged([CallerMemberName] string memberName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(memberName));
}
}
}
Your Subcategories property should be read-only.

Categories

Resources