Hi please could somebody help? I have a ListView which is bound to a ObservableCollection i.e StabCollection. The data displays perfectly.
I have a couple of textboxes and a combo box to enable the user to edit the columns. When those textboxes are edited the values change in the gridview as expected however I am trying to achieve a cancel feature to revert changes back to the original. Manually changing the SelectedItem of StabCollection or changing the StabCollection[SelectedIndex] doesn't update the UI however the collection is changing. Any help will be appreciated.
<Window.DataContext>
<local:MoveStabViewModel/>
</Window.DataContext>
<StackPanel>
<Menu IsEnabled="{Binding ListViewEnabled}">
<MenuItem Header="File"/>
<MenuItem Header="Add" Command="{Binding AddCommand}"/>
<MenuItem Header="Delete"/>
</Menu>
<StackPanel Orientation="Horizontal">
<ListView ItemsSource="{Binding StabCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding ListViewEnabled}" SelectedIndex="{Binding SelectedIndex}" SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10" >
<ListView.Resources>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
<Style TargetType="GridViewColumnHeader">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Padding" Value="5"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Position}" Width="Auto" Header="Position (m)"/>
<GridViewColumn DisplayMemberBinding="{Binding Type}" Width="Auto" Header="Type"/>
<GridViewColumn DisplayMemberBinding="{Binding Pot}" Width="Auto" Header="Tip (mV)"/>
<GridViewColumn DisplayMemberBinding="{Binding Current}" Width="Auto" Header="Current (mA)"/>
<GridViewColumn DisplayMemberBinding="{Binding CurrentDensity}" Width="Auto" Header="Current Density (mA/m2)"/>
<GridViewColumn DisplayMemberBinding="{Binding FieldGradient}" Width="Auto" Header="Field Gradient (uV/cm)"/>
</GridView>
</ListView.View>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding EditCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
<GroupBox Header="Edit Stabs" Width="Auto" Visibility="{Binding IsEdit, Converter={StaticResource BoolToVisConverter }}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="Position" Grid.Column="0" Grid.Row="0"/>
<Label Content="Contact Type" Grid.Column="0" Grid.Row="1"/>
<Label Content="Potential" Grid.Column="0" Grid.Row="3"/>
<TextBox Text="{Binding SelectedItem.Position, Mode=TwoWay}" Grid.Row="0" Grid.Column="1"/>
<ComboBox x:Name="PrintOutComboBox" ItemsSource="{Binding PrintOut}" Width="220" SelectedItem="{Binding SelectedItem.Type, Mode=TwoWay}"
Grid.Row="1" Grid.Column="1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding ButtonOneCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
<ComboBox SelectedIndex="{Binding ElementName=PrintOutComboBox, Path=SelectedIndex}" Width="{Binding ElementName=PrintOutComboBox ,Path=Width}"
ItemsSource="{Binding LongPrintOut}" Grid.Row="2" Grid.Column="1"/>
<TextBox Text="{Binding SelectedItem.Pot, Mode=TwoWay}" Grid.Row="3" Grid.Column="1"/>
<UniformGrid Grid.Row="4" Grid.ColumnSpan="2" Columns="2">
<Button Content="{Binding ButtonOne}" Command="{Binding ButtonOneCommand}"/>
<Button Content="Cancel" Command="{Binding CancelCommand}"/>
</UniformGrid>
</Grid>
</GroupBox>
</StackPanel>
</StackPanel>
public class MoveStabViewModel : INotifyPropertyChanged, IDialogRequestClose
{
ChartEditViewModel VM;
List<AnnotationFile> annotation;
private void OnPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
string[] _printOut;
public string[] PrintOut
{
get { return _printOut; }
set { _printOut = value; }
}
string[] _longPrintOut;
public string[] LongPrintOut
{
get { return _longPrintOut; }
set { _longPrintOut = value; }
}
private string[] SplitCommaDelimitedString(string value)
{
string[] splitString = value.Split(',');
return splitString;
}
ObservableCollection<StabTypes> stabTypes;
public ObservableCollection<StabTypes> StabTypes { get { return stabTypes; } }
public MoveStabViewModel()
{
}
public MoveStabViewModel(ChartEditViewModel VM)
{
this.VM = VM;
annotation = VM.annotation;
PrintOut = new string[21];
LongPrintOut = new string[21];
stabTypes = new ObservableCollection<StabTypes>();
for (int i = 0; i < 20; i++)
{
PrintOut[i] = VM.printOut[i + 1];
LongPrintOut[i] = VM.printLongName[i + 1];
stabTypes.Add(new StabTypes { Code = PrintOut[i], Description = LongPrintOut[i] });
}
EditCommand = new ActionCommand(p => LstContactsDoubleClick());
CancelCommand = new ActionCommand(p => Cancel());
ButtonOneCommand = new ActionCommand(p => ButtonOneMethod());
AddCommand = new ActionCommand(p => Add());
LoadStabs();
}
private void ButtonOneMethod()
{
if (ButtonOne == "Add Stab")
{
}
else
{
//StabCollection[SelectedIndex].Position = SelectedItem.Position;
//StabCollection[SelectedIndex].Pot = SelectedItem.Pot;
//StabCollection[SelectedIndex].Type = DisplayStab;
}
}
private void Add()
{
SelectedItem = null;
DisplayStab = "";
ListViewEnabled = false;
if (SelectedItem != null)
{
DisplayStab = SelectedItem.Type;
}
else
{
DisplayStab = "";
}
ButtonOne = "Add Stab";
WindowSize += 342;
}
public List<string[]> TempAnno { get; set; }
private ObservableCollection<AnnotationBreakDown> _stabBreakdown = new ObservableCollection<AnnotationBreakDown>();
public ObservableCollection<AnnotationBreakDown> StabCollection
{
get { return _stabBreakdown;}
set { _stabBreakdown = value; OnPropertyChanged("StabCollection"); }
}
public ICommand EditCommand { get; }
public ICommand CancelCommand { get; }
public ICommand AddCommand { get; }
public ICommand ButtonOneCommand { get; }
public event EventHandler<DialogCloseRequestedEventArgs> CloseRequested;
public event PropertyChangedEventHandler PropertyChanged;
public void LoadStabs()
{
var annotationFile = new AnnotationFile();
int j = 0;
for (int i = 0; i < annotation.Count; i++)
{
if (annotation[i]._type == "E")
{
var tempStringArray = SplitCommaDelimitedString(annotation[i]._anno);
int stabType = annotationFile.EvalStabType(Strings.Mid(annotation[i]._anno, 1, 1));
bool potCorrectFormat = float.TryParse(tempStringArray[0].Substring(1, 5), out float pot);
bool currentCorrectFormat = float.TryParse(tempStringArray[1], out float current);
bool cdCorrectFormat = float.TryParse(tempStringArray[2], out float cd);
bool fgCorrectFormat = float.TryParse(tempStringArray[3], out float fg);
bool mcCorrectFormat = float.TryParse(tempStringArray[4], out float mc); //McCoy Current
bool mcCDCorrectFormat = float.TryParse(tempStringArray[5], out float mcd);
bool mcFGCorrectFormat = float.TryParse(tempStringArray[6], out float mfg);
StabCollection.Add(new AnnotationBreakDown());
StabCollection[j].Position = Strings.Format(annotation[i]._KP, "#####0.0");
StabCollection[j].Type = VM.printOut[stabType];
if (potCorrectFormat) StabCollection[j].Pot = pot;
if (currentCorrectFormat) StabCollection[j].Current = current;
if (cdCorrectFormat) StabCollection[j].CurrentDensity = cd;
if (fgCorrectFormat) StabCollection[j].FieldGradient = fg;
if (mcCorrectFormat) StabCollection[j].MC = mc;
if (mcCDCorrectFormat) StabCollection[j].MCD = mcd;
if (mcFGCorrectFormat) StabCollection[j].MFG = mfg;
j += 1;
}
}
}
//Are we editing the stabs?
private bool _listviewEnabled = true;
public bool ListViewEnabled
{
get { return _listviewEnabled; }
set { _listviewEnabled = value; OnPropertyChanged("ListViewEnabled"); }
}
//The selected item from listview
private AnnotationBreakDown _selectedItem = new AnnotationBreakDown();
public AnnotationBreakDown SelectedItem
{
get { return _selectedItem; }
set { _selectedItem = value; OnPropertyChanged("SelectedItem"); }
}
private string _displayStab;
public string DisplayStab
{
get { return _displayStab; }
set { _displayStab = value; OnPropertyChanged("DisplayStab"); }
}
//The listview Selected Index
int _selectedIndex;
public int SelectedIndex
{
get { return _selectedIndex; }
set { _selectedIndex = value; OnPropertyChanged("SelectedIndex"); }
}
//Property to store Add/Accept Button
private string _buttonOne = "Accept";
public string ButtonOne
{
get { return _buttonOne; }
set { _buttonOne = value; OnPropertyChanged("ButtonOne"); }
}
string tempPos;
string tempType;
float tempPot;
//Event called when mouse is double clicked on listview
public void LstContactsDoubleClick()
{
if (SelectedItem == null) return;
tempPos = StabCollection[SelectedIndex].Position;
tempType = StabCollection[SelectedIndex].Type;
tempPot = StabCollection[SelectedIndex].Pot;
ListViewEnabled = false;
DisplayStab = SelectedItem.Type;
WindowSize += 342;
}
//Dynamic Window Size CLR property
private int _windowSize = 610;
public int WindowSize
{
get { return _windowSize; }
set { _windowSize = value; OnPropertyChanged("WindowSize"); }
}
public void Cancel()
{
ListViewEnabled = true;
SelectedItem.Type = "GP";
WindowSize -= 342;
}
}
public class StabTypes
{
public string Code { get; set; }
public string Description { get; set; }
public string CodeToolTip
{
get { return Description; }
}
}
public class AnnotationBreakDown
{
public string Position { get; set; }
public string Type { get; set;}
public float Pot { get; set; }
public float Current { get; set; }
public float CurrentDensity { get; set; }
public float FieldGradient { get; set; }
public float MC { get; set; } //McCoy Current
public float MCD { get; set;} //McCoy CD
public float MFG { get; set; } //McCoy FG
}
}
Because ObservableCollection doesn't observe his items. It will raise an event for an insert, delete an item, or reset the collection, not a modification on his item.
So, you must implement ObservableCollection which observe equally his items. This code used in my project found on SO but I can't figure out the post original.
public class ItemsChangeObservableCollection<T> :
System.Collections.ObjectModel.ObservableCollection<T> where T : INotifyPropertyChanged
{
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
RegisterPropertyChanged(e.NewItems);
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
UnRegisterPropertyChanged(e.OldItems);
}
else if (e.Action == NotifyCollectionChangedAction.Replace)
{
UnRegisterPropertyChanged(e.OldItems);
RegisterPropertyChanged(e.NewItems);
}
base.OnCollectionChanged(e);
}
protected override void ClearItems()
{
UnRegisterPropertyChanged(this);
base.ClearItems();
}
private void RegisterPropertyChanged(IList items)
{
foreach (INotifyPropertyChanged item in items)
{
if (item != null)
{
item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
private void UnRegisterPropertyChanged(IList items)
{
foreach (INotifyPropertyChanged item in items)
{
if (item != null)
{
item.PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
//launch an event Reset with name of property changed
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
}
private ItemsChangeObservableCollection<AnnotationBreakDown> _stabBreakdown = new ItemsChangeObservableCollection<AnnotationBreakDown>();
public ItemsChangeObservableCollection<AnnotationBreakDown> StabCollection
{
get { return _stabBreakdown;}
set { _stabBreakdown = value; }
}
Last but not least, your model must implement INotifyPropertyChanged
public class AnnotationBreakDown : INotifyPropertyChanged
{
public string Position { get; set; } // To raise PropertyChanged
public string Type { get; set;} // To raise PropertyChanged
public float Pot { get; set; } // To raise PropertyChanged
public float Current { get; set; } // To raise PropertyChanged
public float CurrentDensity { get; set; } // To raise PropertyChanged
public float FieldGradient { get; set; } // To raise PropertyChanged
public float MC { get; set; } //McCoy Current
public float MCD { get; set;} //McCoy CD
public float MFG { get; set; } //McCoy FG
}
Related
I just began working with the MVVM layout and I cannot seem to display anything in my collectionView List. I believe it's my binding, unfortunately I don't really understand how I am supposed to bind a grouped list + the ViewModel. I read to bind to the path no the source, but I'm pretty sure I am doing this incorrectly. I have checked to see if I am even getting shares to load and I am, they're just not displaying.
Model -- Share
[JsonProperty("iSpottedID")]
public int ID { get; set; }
[JsonProperty("sShoppingList")]
[MaxLength(255)]
public string ShoppingName { get; set; }
[JsonProperty("dtInfoUpdate")]
[MaxLength(20)]
public string CreateDate { get; set; }
[JsonProperty("iProductID")]
public int ProductID { get; set; }
[Indexed]
[JsonProperty("sLocation")]
[MaxLength(255)]
public string LocationName { get; set; }
[JsonProperty("tvCardJson")]
public string JsonString { get; set; }
ViewModel -- SharesViewModel
public class SharesViewModel : BaseViewModel
{
#region Properties
private int _id;
public int ID
{
get { return _id; }
set
{
SetValue(ref _id, value);
OnPropertyChanged(nameof(ID));
}
}
private string _longName;
public string LongName
{
get { return _longName; }
set
{
SetValue(ref _longName, value);
OnPropertyChanged(nameof(LongName));
}
}
private string _date;
public string CreateDate
{
get{ return _date;}
set
{
SetValue(ref _date, value);
OnPropertyChanged(nameof(CreateDate));
}
}
private int _prodID;
public int ProductID
{
get { return _id; }
set
{
SetValue(ref _prodID, value);
OnPropertyChanged(nameof(ProductID));
}
}
private string _json;
public string JsonString
{
get { return _json; }
set
{
SetValue(ref _json, value);
OnPropertyChanged(nameof(JsonString));
}
}
private string _location;
public string LocationName
{
get { return _location; }
set
{
SetValue(ref _location, value);
OnPropertyChanged(nameof(LocationName));
}
}
//ADD-ONS
public string Address
{
get
{
if (!string.IsNullOrEmpty(JsonString))
{
var jsonDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonString);
if (jsonDict.ContainsKey("address"))
if (jsonDict["address"] != "")
return jsonDict["address"];
}
return null;
}
}
private ImageSource _imageLink;
public ImageSource ImageLink
{
get
{
if(ProductID != 0)
{
...
return ImageSource.FromUri(link);
}
return null;
}
}
#endregion
public SharesViewModel(){}
public SharesViewModel(Share share)
{
ID = share.ID;
ProductID = share.ProductID;
JsonString = share.JsonString;
CreateDate = share.CreateDate;
LocationName = share.LocationName;
}
List View Model -- SharesListViewlModel
public class SharesListViewModel : BaseViewModel
{
private SharesViewModel _selectedShare;
private bool _isDataLoaded;
//grouped list
public ObservableCollection<LocationSpotGroups<string, SharesViewModel>> Shares { get; set; }
...
public ICommand OpenMoreSharesCommand { get; private set; }
public ICommand LoadDataCommand { get; private set; }
public SharesListViewModel(Position NW , Position SE)
{
_nw = NW;
_se = SE;
LoadDataCommand = new Command(async () => await LoadData());
OpenMoreSharesCommand = new Command<SharesViewModel>(async (share) => await OpenMoreShares(share));
public ObservableCollection<SharesViewModel> sList { get; set; }
= new ObservableCollection<SharesViewModel>();
}
private async Task LoadData()
{
if (_isDataLoaded)
return;
var list = await _connection.GetAllRegionShares(_nw, _se);
foreach (var spot in list)
{
sList.Add(new SharesViewModel(spot));
}
var sorted = from item in sList
orderby item.LocationName
group item by item.LocationName into itemGroup
select new LocationSpotGroups<string, SharesViewModel>(itemGroup.Key, itemGroup);
Shares = new ObservableCollection<LocationSpotGroups<string, SharesViewModel>>(sorted);
}
LocationSpotGroups
public class LocationSpotGroups<K, T> : ObservableCollection<T>
{
public K GroupKey { get; set; }
public IEnumerable<T> GroupedItem { get; set; }
public LocationSpotGroups(K key, IEnumerable<T> shares)
{
GroupKey = key;
GroupedItem = shares;
foreach (var item in shares)
{
this.Items.Add(item);
}
}
}
SharesPage XAML
<CollectionView x:Name="CollectionList"
VerticalOptions="FillAndExpand"
ItemsSource="{Binding Shares}"
IsGrouped="True">
<!--HEADER-->
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal"
Padding="5"
BackgroundColor="#f7f7fb">
<Label x:Name="labelname"
Text="{Binding GroupKey}"
HorizontalOptions="Start"
VerticalOptions="Center"
TextColor="gray" />
</StackLayout>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<!--BODY-->
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="5" Margin="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ImageButton Source="{Binding ImageLink}"
WidthRequest="150"
HeightRequest="150"
Grid.ColumnSpan="2"
CornerRadius="15"
Aspect="AspectFill"
Grid.Row="0"
Grid.Column="0"/>
<Label Text="{Binding ShoppingName}"
Grid.Row="1"
Grid.Column="0"/>
<Label Text="More"
Grid.Row="1"
Grid.Column="1"
HorizontalTextAlignment="End"/>
<Label Text="{Binding CreateDate}"
Grid.Row="2"
Grid.Column="0"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
SharesPage CS
public SharesPage( Position NW, Position SE )
{
InitializeComponent();
ViewModel = new SharesListViewModel(NW, SE);
}
public SharesListViewModel ViewModel
{
get { return BindingContext as SharesListViewModel; }
set { BindingContext = value; }
}
protected override void OnAppearing()
{
ViewModel.LoadDataCommand.Execute(null);
base.OnAppearing();
}
Loading the data in the constructor works if the data is not a lot, which is wasn't in my case. Everything loads perfectly.
I am just new to WPF, Caliburn.Micro and Dapper. I have three combo boxes: the first one is for the region, the second one is for the provinces in the particular selected region and the third one are the cities in the particular selected province. What I want to achieve is that when I selected a particular region it will display all the provinces in that region, the same with the province combo box, when selected it will display all the cities associated with that province. Can this be done in a single method? Here is my code so far.
DataAccess
public List<RegionModel> GetRegion_All()
{
List<RegionModel> output;
using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(GlobalConfig.CnnString(db)))
{
output = connection.Query<RegionModel>("dbo.spRegion_GetAll").ToList();
var p = new DynamicParameters();
foreach (RegionModel region in output)
{
p = new DynamicParameters();
p.Add("#RegionId", region.Id);
region.Provinces = connection.Query<ProvinceModel>("dbo.spProvince_ByRegion", p, commandType: CommandType.StoredProcedure).ToList();
foreach (ProvinceModel province in region.Provinces)
{
p = new DynamicParameters();
p.Add("#ProvinceId", province.Id);
region.Cities = connection.Query<CityModel>("dbo.spCity_ByProvince", p, commandType: CommandType.StoredProcedure).ToList();
}
}
}
return output;
}
Models
public class RegionModel
{
public int Id { get; set; }
public string Region { get; set; }
public string RegionName { get; set; }
public List<ProvinceModel> Provinces { get; set; } = new List<ProvinceModel>();
public List<CityModel> Cities { get; set; } = new List<CityModel>();
public List<BarangayModel> Barangays { get; set; } = new List<BarangayModel>();
}
public class ProvinceModel
{
public int Id { get; set; }
public string Province { get; set; }
public int RegionId { get; set; }
}
public class CityModel
{
public int Id { get; set; }
public string City { get; set; }
public int ProvinceId { get; set; }
public int ZipCode { get; set; }
}
ViewModel
public class ShellViewModel : Screen
{
private BindableCollection<RegionModel> _region;
private RegionModel _selectedRegion;
private ProvinceModel _selectedProvince;
public ShellViewModel()
{
GlobalConfig.InitializeConnections(DatabaseType.Sql);
Region = new BindableCollection<RegionModel>(GlobalConfig.Connection.GetRegion_All());
}
public BindableCollection<RegionModel> Region
{
get { return _region; }
set
{
_region = value;
}
}
public RegionModel SelectedRegion
{
get { return _selectedRegion; }
set
{
_selectedRegion = value;
NotifyOfPropertyChange(() => SelectedRegion);
}
}
public ProvinceModel SelectedProvince
{
get { return _selectedProvince; }
set
{
_selectedProvince = value;
NotifyOfPropertyChange(() => SelectedRegion);
}
}
View
<Window x:Class="WPFUI.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFUI.Views"
mc:Ignorable="d" WindowStartupLocation="CenterScreen"
Title="ShellView" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" x:Name="Region" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding RegionName}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox Grid.Row="1" x:Name="SelectedRegion_Provinces" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Province}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox Grid.Row="2" x:Name="SelectedRegion_Cities" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding City}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Most of my codes ideas are from the tutorials I found in youtube, since references and materials for WPF, Caliburn.Micro and Dapper are very hard to find. Please be patient with my code :)
You have lot of mistake and you dont use the power of Caliburn
The wpf definition:
with Caliburn if you give name Region for combobox, it waits a bindableCollection with same name (Region) and SelectedItem is named SelectedRegion
(see name convention with Caliburn). So i choose Region, Province & City
In the different models i have renamed all strings RegionName, ProvinceName and CityName.
<ComboBox Grid.Row="0" x:Name="Region" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding RegionName}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox Grid.Row="1" x:Name="Province" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ProvinceName}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox Grid.Row="2" x:Name="City" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CityName}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
then, i have modified your class definition:
public class RegionModel:PropertyChangedBase
{
public int Id { get; set; }
public string Region { get; set; }
public string RegionName { get; set; }
// each Region has its Provinces
public List<ProvinceModel> Provinces { get; set; } = new List<ProvinceModel>();
}
public class ProvinceModel:PropertyChangedBase
{
public int Id { get; set; }
public string ProvinceName { get; set; }
public int RegionId { get; set; }
// each Province has its Cities
public List<CityModel> Cities { get; set; } = new List<CityModel>();
}
public class CityModel:PropertyChangedBase
{
public int Id { get; set; }
public string CityName { get; set; }
public int ProvinceId { get; set; }
public int ZipCode { get; set; }
}
Then in ViewModel i add the different BindableCollection Region, Province & City dont forget to add
using Caliburn.Micro;
in the using definion. Then Add the Selected Definition
public class ShellViewModel : Screen
{
private RegionModel selectedRegion;
private ProvinceModel selectedProvince;
private CityModel selectedCity;
private BindableCollection<RegionModel> _region;
private BindableCollection<ProvinceModel> _province;
private BindableCollection<CityModel> _city;
public BindableCollection<RegionModel> Region
{
get { return _region; }
set
{
_region = value;
NotifyOfPropertyChange(() => Region);
}
}
public BindableCollection<ProvinceModel> Province
{
get { return _province; }
set
{
_province = value;
NotifyOfPropertyChange(() => Province);
}
}
public BindableCollection<CityModel> City
{
get { return _city; }
set
{
_city = value;
NotifyOfPropertyChange(() => City);
}
}
public RegionModel SelectedRegion
{
get { return selectedRegion; }
set
{
selectedRegion = value;
NotifyOfPropertyChange(() => SelectedRegion);
Province.Clear();
Province.AddRange(selectedRegion.Provinces);
NotifyOfPropertyChange(() => Province);
}
}
public ProvinceModel SelectedProvince
{
get { return selectedProvince; }
set
{
selectedProvince = value;
NotifyOfPropertyChange(() => SelectedProvince);
City.Clear();
City.AddRange(selectedProvince.Cities);
NotifyOfPropertyChange(() => City);
}
}
public CityModel SelectedCity
{
get { return selectedCity; }
set
{
selectedCity = value;
NotifyOfPropertyChange(() => SelectedCity);
}
}
public ShellViewModel()
{
// to DO INITIALIZE Regions
//
Province = new BindableCollection<ProvinceModel>();
City = new BindableCollection<CityModel>();
Region = new BindableCollection<RegionModel>(Regions);
}
and you have a functional sample
Each time you select a region, the associated provinces are loaded and same thing if you select a province for the associated Cities
I have a TreeView, where I want to add an item with a right click. Therefore I use a command, to insert a new item.
The problem is now that adding/removing items won't be reflected in the UI and I don't know why.
The ObersavableCollections are hold in a property in my MainWindow
public static ObservableCollection<PlantObject> PlantObjects { get; set; }
The code works the way I want thus if I check the property and the item itself, it will be added but the TreeView will not reflect the changes. This can be shown by setting the ItemsSource of the TreeView null and then again to PlantObjects, which then displays the added item.
I'm pretty sure it the problem is that I add an item to the property "parents". But I don't know how to solve it.
You can see my Xaml and my Class below. NotifyPropertyChanged is implemented.
Thanks for any advice.
XAML
<TreeView Name="ContextTreeView" Margin="0,9.8,0.8,5" Grid.Row="1" Grid.Column="0" ItemsSource="{Binding Source={x:Static local:MainWindow.PlantObjects} }">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:PlantObject}" ItemsSource="{Binding PlantObjects}" >
<StackPanel Orientation="Horizontal">
<StackPanel.ContextMenu>
<ContextMenu >
<MenuItem Header="Delete" Name="MenuItem_DeleteContextType" Command="{Binding DeleteContextTypeCommand}"/>
<MenuItem Header="Insert new object above" Name="ContextMenuItem_InsertAbovePlantObject" Command="{Binding InsertAboveCommand}"/>
</ContextMenu>
</StackPanel.ContextMenu>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
My Class
public class PlantObject : INotifyPropertyChanged
{
public PlantObject()
{
CreateInsertAboveCommand();
}
private bool _IsSelected;
private PlantObject parent;
private string name;
public byte[] ParentID { get; set; }
public byte[] ChildID { get; set; }
public byte[] ObjectID { get; set; }
private ObservableCollection<PlantObject> plantObjects = new ObservableCollection<PlantObject>();
public PlantObject Parent
{
get
{
return parent;
}
set
{
if (value != parent)
{
parent = value;
NotifyPropertyChanged();
}
}
}
public string Name
{
get
{
return name;
}
set
{
if (value != name)
{
name = value;
NotifyPropertyChanged();
}
}
}
public ObservableCollection<PlantObject> PlantObjects
{
get { return plantObjects; }
set
{
//ignore if values are equal
if (value == plantObjects) return;
plantObjects = value;
NotifyPropertyChanged();
}
}
public bool IsSelected
{
get { return _IsSelected; }
set
{
if (_IsSelected == value) return;
_IsSelected = value;
NotifyPropertyChanged();
}
}
public int? GetPosition(PlantObject plantObject)
{
int count = 0;
foreach (var childObject in this.plantObjects)
{
if (plantObject == childObject)
{
return count;
}
count++;
}
return null;
}
protected void Insert(int position, PlantObject plantObject)
{
Parent.PlantObjects.Insert(position, plantObject);
}
protected void Remove(PlantObject plantObject)
{
Parent.PlantObjects.RemoveAt(Parent.PlantObjects.IndexOf(plantObject));
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#region commands
#region InsertAbove Command
public ICommand InsertAboveCommand
{
get;
internal set;
}
private bool CanExecuteInsertAboveCommand()
{
return true;
}
private void CreateInsertAboveCommand()
{
InsertAboveCommand = new RelayCommand(InsertAbove);
}
public void InsertAbove(object obj)
{
//this.IsSelected = true;
if (this.parent == null)
{ //highest level
MainWindow.PlantObjects.Insert(MainWindow.PlantObjects.IndexOf(this), new PlantObject {IsSelected = true, Parent = this.Parent });
return;
}
int position = this.parent.GetPosition(this) ?? default(int);
PlantObject newPlantObejct = new PlantObject { Parent = this.Parent, IsSelected = true };
this.Insert(position, newPlantObejct);
}
#endregion
#endregion
}
I have this TreeView control:
<TreeView x:Name="treeView" HorizontalAlignment="Left" Margin="0" Width="300" ItemsSource="{Binding TvMview.FirstNodes}"
VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SecondNodes}">
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding ThirdNodes}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding HeaderText}" Background="Red"/>
</StackPanel>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text=">>> " Background="Green"/>
<TextBlock Text="{Binding HeaderText}" Background="blue"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
Binded to:
public class ModelView
{
public TreeViewModelView TvMview { get; set; } = new TreeViewModelView();
}
public class TreeViewModelView
{
public ObservableCollection<FirstNode> FirstNodes { get; set; } = new ObservableCollection<FirstNode>();
}
public class FirstNode : TreeItem
{
public ObservableCollection<SecondNode> SecondNodes { get; set; } = new ObservableCollection<SecondNode>();
public string HeaderText { get; set; }
}
public class SecondNode : TreeItem
{
public ObservableCollection<ThirdNode> ThirdNodes { get; set; } = new ObservableCollection<ThirdNode>();
public string HeaderText { get; set; }
}
public class ThirdNode
{
public string HeaderText { get; set; }
}
public class TreeItem
{
public bool IsExpanded { get; set; }
public bool IsSelected { get; set; }
}
And everything is working as expected. But... I want to implement seach:
foreach (var firstNode in Mview.TvMview.FirstNodes)
{
if (firstNode.HeaderText.Contains(textBox.Text))
{
firstNode.IsExpanded = true;
firstNode.IsSelected = true;
TreeViewItem tvItem = (TreeViewItem)treeView.ItemContainerGenerator.ContainerFromItem(firstNode);
tvItem?.Focus();
return;
}
}
The right node is expanded but tvItem is always null. I read somewhere sometime that ContainerFromItem doesn't likes virtualization...
Any idea?
Thanks!
Finally i solved this issue implementing a Focus() method in the TreeItem base class. So, base class look like this:
public class TreeItem : INotifyPropertyChanged
{
private bool _IsExpanded;
public bool IsExpanded
{
get { return _IsExpanded; }
set { _IsExpanded = value; OnPropertyChanged("IsExpanded"); }
}
private bool _IsSelected;
public bool IsSelected
{
get { return _IsSelected; }
set { _IsSelected = value; OnPropertyChanged("IsSelected"); }
}
public void Focus(TreeView tView)
{
TreeViewItem tvItem = (TreeViewItem)tView.ItemContainerGenerator.ContainerFromItem(this);
tvItem?.Focus();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
And you can call it like this:
if (firstNode.HeaderText.Contains(textBox.Text))
{
firstNode.IsExpanded = true;
firstNode.IsSelected = true;
firstMatch.Focus();
}
I wrote a program with MVVM (C#) and XAML using Caliburn.Micro library, how can i:
get all selected items (not only one item)?
get selected change event?
sort items by clicking header columns?
Any help would be appreciated.
GUI code: Views \ MainView.xaml
<Window x:Class="ListBox_CaliburnMicro.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:vm="clr-namespace:ListBox_CaliburnMicro"
WindowStartupLocation="CenterScreen"
Title="MainWindow" Height="300" Width="600">
<Grid>
<Grid.DataContext>
<vm:MainViewModel/>
</Grid.DataContext>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="153*"/>
</Grid.ColumnDefinitions>
<Button Command="{Binding HelloCommand}" Content="Hello ..." HorizontalAlignment="Left" Margin="10,36,0,0" VerticalAlignment="Top" Width="75" ToolTip="Test" Background="White" Foreground="Black" Height="22" />
<Button Content="Add" Command="{Binding AddCommand}" HorizontalAlignment="Left" Margin="10,8,0,0" VerticalAlignment="Top" Width="75" ToolTip="Add item end of list" Background="White" Foreground="Black" Height="22"/>
<Button Content="Delete" Command="{Binding DeleteCommand}" HorizontalAlignment="Left" Margin="96,8,0,0" VerticalAlignment="Top" Width="75" ToolTip="Delete first item from list" Background="White" Foreground="Black" Height="22"/>
<Button Content="Update" Command="{Binding UpdateCommand}" HorizontalAlignment="Left" Margin="184,8,0,0" VerticalAlignment="Top" Width="75" ToolTip="Update first item from list" Background="White" Foreground="Black" Height="22"/>
<Button Content="GetSelectedItem" Command="{Binding GetSelectedItemCommand}" HorizontalAlignment="Left" Margin="271,8,0,0" VerticalAlignment="Top" Width="95" ToolTip="get selected item from list" Background="White" Foreground="Black" Height="22"/>
<Button Content="GetItem:" Command="{Binding GetItemXCommand}" HorizontalAlignment="Left" Margin="377,8,0,0" VerticalAlignment="Top" Width="75" ToolTip="get item x, from list" Background="White" Foreground="Black" Height="22"/>
<TextBox x:Name="ItemX" Text="0" HorizontalAlignment="Left" Height="20" Margin="455,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="70"/>
<TextBlock x:Name="OuputText" HorizontalAlignment="Left" Height="20" Margin="165,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="415" Foreground="#FFFF0909"/>
<Label Content="Output:" HorizontalAlignment="Left" Height="28" Margin="100,35,0,0" VerticalAlignment="Top" Width="55"/>
<ListView Grid.Column="1" x:Name="FileListView" SelectionMode="Extended" SelectedItem="{Binding SelectedItem}" SelectedIndex="{Binding SelectedIndex}" ItemsSource="{Binding Path=Files}" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch" Margin="10,65,10,10" Foreground="Black" Background="#FFE6EEF7">
<ListView.View>
<GridView>
<GridViewColumn Header="Status" Width="Auto"
DisplayMemberBinding="{Binding FileStatus}"/>
<GridViewColumn Header="Name" Width="Auto"
DisplayMemberBinding="{Binding FileName}"/>
<GridViewColumn Header="Size" Width="Auto"
DisplayMemberBinding="{Binding FileSize}"/>
<GridViewColumn Header="System Type" Width="Auto"
DisplayMemberBinding="{Binding FileType}"/>
<GridViewColumn Header="Email Count" Width="Auto"
DisplayMemberBinding="{Binding FileEmailCount}"/>
<GridViewColumn Header="Info Count" Width="Auto"
DisplayMemberBinding="{Binding FileInfoCount}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
ViewModel code: ViewModels \ MainViewModel.cs
using Caliburn.Micro;
using ListBox_CaliburnMicro.Model;
using ListBox_CaliburnMicro.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace ListBox_CaliburnMicro
{
public class MainViewModel : Screen, INotifyPropertyChanged
{
public MainViewModel()
{
FillDataFile();
HelloCommand = new RelayCommand(DoHello, CanDoHello);
AddCommand = new RelayCommand(DoAdd, CanDoAdd);
DeleteCommand = new RelayCommand(DoDelete, CanDoDelete);
UpdateCommand = new RelayCommand(DoUpdate, CanDoUpdate);
GetSelectedItemCommand = new RelayCommand(DoGetSelectedItem, CanDoGetSelectedItem);
GetItemXCommand = new RelayCommand(DoGetGetItemX, CanDoGetItemX);
}
#region File listView
private ObservableCollection<File> _Files;
public ObservableCollection<File> Files
{
get { return _Files; }
set
{
_Files = value;
OnPropertyChanged("Files");
}
}
private void FillDataFile()
{
_Files = new ObservableCollection<File>();
for (int i = 0; i < 100000; i++)
{
string strName = string.Format("{0}", i);
_Files.Add(new File() { FileStatus = "status", FileName = strName, FileSize = i, FileType = "type", FileEmailCount = "email_count", FileInfoCount = "info_count" });
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
#region OuputText textbox
private string _OuputText = "-";
public string OuputText
{
get
{
return _OuputText;
}
set
{
_OuputText = value;
OnPropertyChanged("OuputText");
}
}
#endregion
#region ItemX textbox
private string _ItemX = "0";
public string ItemX
{
get
{
return _ItemX;
}
set
{
int nItem = 0;
if (Int32.TryParse(value, out nItem))
{
if (nItem >= _Files.Count || nItem < 0)
return;
}
_ItemX = value;
OnPropertyChanged("ItemX");
}
}
#endregion
#region command button
#region Hello button
public RelayCommand HelloCommand { get; set; }
private bool CanDoHello(object obj)
{
return true;
}
private void DoHello(object obj)
{
System.Windows.MessageBox.Show("DoHello");
}
#endregion
#region Add button
public RelayCommand AddCommand { get; set; }
private bool CanDoAdd(object obj)
{
return true;
}
private void DoAdd(object obj)
{
string strName = string.Format("{0}", _Files.Count + 1);
_Files.Add(new File() { FileStatus = "status", FileName = strName, FileSize = _Files.Count, FileType = "type", FileEmailCount = "email_count", FileInfoCount = "info_count" });
}
#endregion
#region Delete button
public RelayCommand DeleteCommand { get; set; }
private bool CanDoDelete(object obj)
{
if (_Files.Count > 0)
return true;
return false;
}
private void DoDelete(object obj)
{
if (_Files.Count > 0)
{
if (SelectedItem != null)
_Files.Remove(SelectedItem);
else
_Files.RemoveAt(0);
}
}
#endregion
#region Update button
public RelayCommand UpdateCommand { get; set; }
private bool CanDoUpdate(object obj)
{
if (_Files.Count > 0)
return true;
return false;
}
private void DoUpdate(object obj)
{
// var vvv= SelectedItems;
if (_Files.Count > 0)
{
if (SelectedItem != null)
SelectedItem.FileName = "Updated ..."; // change FileName field
else
_Files[0].FileName = "Updated ...";
}
// List<File> FilesSelect = _Files.Where(p => p.FileID == _Files[0].FileID).ToList();
}
#endregion
#region GetSelectedItem button
public RelayCommand GetSelectedItemCommand { get; set; }
private bool CanDoGetSelectedItem(object obj)
{
if (_Files.Count > 0)
return true;
return false;
}
public File SelectedItem { get; set; }
public int SelectedIndex { get; set; }
private void DoGetSelectedItem(object obj)
{
if (_Files.Count > 0 && SelectedItem != null)
{
var selected_file = SelectedItem;
OuputText = string.Format("first selected index {0} -> [{1}]", SelectedIndex, selected_file.FileID);
}
}
#endregion
#region GetItemX button
public RelayCommand GetItemXCommand { get; set; }
private bool CanDoGetItemX(object obj)
{
if (_Files.Count > 0)
return true;
return false;
}
private void DoGetGetItemX(object obj)
{
int nItem = 0;
if (Int32.TryParse(ItemX, out nItem))
{
if (nItem < _Files.Count)
{
OuputText = string.Format("select index {0} -> [{1}]", nItem, _Files[nItem].FileID);
}
}
else
OuputText = "-";
}
#endregion
#endregion
}
}
ICommand code: ViewModels \ RelayCommand.cs
using System;
using System.Windows.Input;
namespace ListBox_CaliburnMicro.ViewModels
{
public class RelayCommand : ICommand
{
#region field
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion
#region constructors
public RelayCommand(Action<object> execute) : this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion
#region member
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion
#region raise
public void RaiseCanExecuteChanged()
{
/*if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);*/
}
#endregion
}
}
Model code: Model \ File.cs
using System;
using System.ComponentModel;
namespace ListBox_CaliburnMicro.Model
{
public class File : INotifyPropertyChanged
{
private Guid _FileID;
public Guid FileID
{
get
{
return _FileID;
}
set
{
_FileID = value;
OnPropertyChanged("FileID");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private string _FileStatus;
public string FileStatus
{
get
{
return _FileStatus;
}
set
{
_FileStatus = value;
OnPropertyChanged("FileStatus");
}
}
private string _FileName;
public string FileName
{
get
{
return _FileName;
}
set
{
_FileName = value;
OnPropertyChanged("FileName");
}
}
public int _FileSize;
public int FileSize
{
get
{
return _FileSize;
}
set
{
_FileSize = value;
OnPropertyChanged("FileSize");
}
}
private string _FileType;
public string FileType
{
get
{
return _FileType;
}
set
{
_FileType = value;
OnPropertyChanged("FileType");
}
}
private string _FileEmailCount;
public string FileEmailCount
{
get
{
return _FileEmailCount;
}
set
{
_FileEmailCount = value;
OnPropertyChanged("FileEmailCount");
}
}
private string _FileInfoCount;
public string FileInfoCount
{
get
{
return _FileInfoCount;
}
set
{
_FileInfoCount = value;
OnPropertyChanged("FileInfoCount");
}
}
public File()
{
FileID = Guid.NewGuid();
}
public File(string s1 = "", string s2 = "", int s3 = 0, string s4 = "", string s5 = "", string s6 = "")
{
FileID = Guid.NewGuid();
FileStatus = s1;
FileName = s2;
FileSize = s3;
FileType = s4;
FileEmailCount = s5;
FileInfoCount = s6;
}
}
}
You have to hook up these events to a command and process them in the viewmodel.
Not using Caliburn.Micro but there should also be a concept for EventToCommand Binding. I quick search revealed the following links.
https://caliburnmicro.codeplex.com/wikipage?title=Cheat%20Sheet
https://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions
http://www.mindscapehq.com/blog/index.php/2012/01/24/caliburn-micro-part-3-more-about-events-and-parameters/
if I did not get your question correct please let me know...
HTH