How to binding XDocument element to combobox in MVVM? - c#

I have a XDocument read from xml file:
public ObservableCollection<Product> GetProducts()
{
ObservableCollection<Product> _products = new ObservableCollection<Product>();
XDocument doc = XDocument.Load(#".\Config\MCU.xml");
foreach (XElement productRow in doc.Root.Elements("MCU"))
{
var m = new Product(productRow.Element("MCUName").Value, Convert.ToUInt32(productRow.Element("MCUNumber").Value), Convert.ToUInt32(productRow.Element("FlashAddress").Value),
Convert.ToUInt32(productRow.Element("PageCount").Value), Convert.ToUInt32(productRow.Element("PageSize").Value), productRow.Element("BinFile").Value,
Convert.ToUInt32(productRow.Element("RAMCodeAdd").Value), Convert.ToUInt32(productRow.Element("MainCR").Value), Convert.ToUInt32(productRow.Element("CRTrimmingAdd").Value),
Convert.ToUInt32(productRow.Element("CRTrimmingLength").Value), Convert.ToUInt32(productRow.Element("UIDAdd").Value), Convert.ToByte(productRow.Element("UIDLength").Value),
productRow.Element("UID").Value, productRow.Element("UserArea").Value);
_products.Add(m);
}
return _products;
}
Now I want to binding XElement MCUName to combobox:
<ComboBox x:Name="cb_MCUType" SelectedItem="{Binding MCUName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
ItemsSouce in the code behind:
public MainWindow()
{
InitializeComponent();
cb_MCUType.ItemsSource = App.ProductDb.GetProducts();
}
But this doesn't work, the combobox populate the Product, how should I fix this? Thanks!
Update:
Thanks for the replies. As you suggested, now I would like to write this in MVVM, so I change my original code:
XAML:
<ComboBox x:Name="cb_MCUType" ItemsSource="{Binding ProductsList}" SelectedValue="{Binding SelectedProduct}" DisplayMemberPath="MCUName" />
ViewModel:
public class MainViewModel : INotifyPropertyChanged
{
private ProductDB pd = new ProductDB();
public MainViewModel()
{
DefaultValue_Load();
}
public ObservableCollection<Product> ProductsList { get; set; }
private Product _selectedProduct;
public Product SelectedProduct
{
get { return _selectedProduct; }
set
{
_selectedProduct = value;
NotifyPropertyChanged("SelectedProduct");
}
}
public void DefaultValue_Load()
{
ProductsList = new ObservableCollectioin<Product>(pd.GetProducts());
}
}

When you create the Products in GetProducts() you provide MCUName as the first parameter in the constructor. For the following sample, I'll assume, that there is a property McuName on every product:
public MainWindow()
{
InitializeComponent();
cb_MCUType.ItemsSource = App.ProductDb.GetProducts().Select(p => p.McuName);
}
It is worth to mention, that this is not a clean MVVM implementation. You should consider to redesign your application to follow the MVVM patter.

Related

C# WPF ComboBox ItemsSource Binding Issue

I have an issue with binding ComboBox ItemsSource with a list. I read workplaces from csv file. It can't see the Workplaces list. Please, tell me what is wrong.
xaml:
<ComboBox Grid.Column="1" Grid.Row="9" Height="25" Margin="0,18,0,0" ItemsSource="{Binding Workplaces}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding title}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
xaml.cs:
public partial class MainWindow : Window
{
private BindableCollection<WorkplaceInfo> Workplaces { get; set; }
public MainWindow()
{
InitializeComponent();
Workplaces = new BindableCollection<WorkplaceInfo>(GetWorkplaces());
}
private List<WorkplaceInfo> GetWorkplaces()
{
List<WorkplaceInfo> workplaces = new List<WorkplaceInfo>();
using (var streamReader = new StreamReader("Workplaces.csv"))
{
using (var csvReader = new CsvReader(streamReader, CultureInfo.InvariantCulture))
{
//csvReader.Context.RegisterClassMap<WorkplaceInfoClassMap>();
var workplaceInfoList = csvReader.GetRecords<dynamic>().ToList();
foreach (var wi in workplaceInfoList)
{
workplaces.Add(new WorkplaceInfo(wi.title, wi.member_of.Split(";")));
}
}
}
return workplaces;
}
}
WorkplaceInfo class:
class WorkplaceInfo
{
public String title { get; }
public String[] memberOfList { get; }
public WorkplaceInfo(string title, string[] memberOfList)
{
this.title = title;
this.memberOfList = memberOfList;
}
}
Here is your code optimized to work:
public ObservableCollection<WorkplaceInfo> Workplaces { get; set; }
public MainWindow()
{
this.DataContext = this;
Workplaces = new ObservableCollection<WorkplaceInfo>(GetWorkplaces());
InitializeComponent();
}
private List<WorkplaceInfo> GetWorkplaces()
{
List<WorkplaceInfo> workplaces = new List<WorkplaceInfo>();
try
{
using (var streamReader = new StreamReader("Workplaces.csv"))
{
using (var csvReader = new CsvReader(streamReader, CultureInfo.CurrentCulture))
{
//csvReader.Context.RegisterClassMap<WorkplaceInfoClassMap>();
var workplaceInfoList = csvReader.GetRecords<dynamic>().ToList();
foreach (var wi in workplaceInfoList)
{
var titl = wi.title;
workplaces.Add(new WorkplaceInfo(wi.title, new List<string>() { wi.member_of }.ToArray()));
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return workplaces;
}
So the changes needed in your code are:
Set your Workplaces collection to public ObservableCollection
Add DataContext binding
Read in the Date and create the collection before the main window is initialized (other way round the UI will not detect the change in you object unless you implement INotifyPropertyChanged event)
p.s. I don't know the structure of your csv file so I made my small demo like (Workplaces.csv) and adopted the parser. You can keep your parser if it matches your csv file structrue.:
title;member_of
London;First
Amsterdam;Second
And my warm recommendation is to use try-catch block always when handling files and when working with anything what is external to your application.
Best regards.

C# Xamarin Forms Populating CollectionView from ViewModel is always null

I am trying to populate a collection view from a ViewModel, however when I try to bind the data to the collection view, the ViewModel is null.
xaml.cs file
ObservableCollection<ReportsClass> newKidList = new ObservableCollection<ReportsClass>();
public ReportsViewModel viewmodel { get; set; }
public ReportsPage()
{
InitializeComponent();
viewmodel = new ReportsViewModel();
this.BindingContext = viewmodel;
PreviousDateRange.CornerRadius = 20;
NextDateRange.CornerRadius = 20;
DateTime firstDate = currentDate.StartOfWeek(DayOfWeek.Sunday);
DateTime secondDate = currentDate.AddDays(7).StartOfWeek(DayOfWeek.Saturday);
DateRange.Text = firstDate.ToString("MMMM d") + " - " + secondDate.ToString("MMMM d");
Kids.SetBinding(ItemsView.ItemsSourceProperty, nameof(viewmodel.kids));
}
Here is my view model
public class ReportsViewModel
{
public ObservableCollection<ReportsClass> kids { get; set; }
FirebaseStorageHelper firebaseStorageHelper = new FirebaseStorageHelper();
WebServiceClass webServiceClass = new WebServiceClass();
DateTime currentDate = DateTime.Now;
public ReportsViewModel()
{
GetKids();
}
public async void GetKids()
{
var parentId = await SecureStorage.GetAsync("parentid");
kids = await webServiceClass.Reports(Convert.ToInt32(parentId), currentDate.StartOfWeek(DayOfWeek.Sunday), currentDate.AddDays(7).StartOfWeek(DayOfWeek.Saturday));
}
}
And here is the method that gets the data for the view model
public async Task<ObservableCollection<ReportsClass>> Reports(int parentid, DateTime startDate, DateTime endDate)
{
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("parentid", parentid.ToString()),
new KeyValuePair<string, string>("startDate", startDate.ToString("yyyy-MM-dd H:mm:ss")),
new KeyValuePair<string, string>("endDate", endDate.ToString("yyyy-MM-dd"))
});
var response = await client.PostAsync(string.Format("https://example.com/api/index.php?action=reports"), content);
var responseString = await response.Content.ReadAsStringAsync();
ObservableCollection<ReportsClass> items = JsonConvert.DeserializeObject<ObservableCollection<ReportsClass>>(responseString);
return items;
}
What am I doing wrong? The purpose of me doing it this way is so I can update an item in the collectionview
Here is my ReportsClass
public class ReportsClass
{
public ReportsClass(string firstName)
{
first_name = firstName;
}
public string first_name { get; set; }
}
OPTION A:
Fix the syntax of Kids.SetBinding, to not get null. Refer to the CLASS ReportsViewModel, not to the INSTANCE viewmodel:
Kids.SetBinding(ItemsView.ItemsSourceProperty, nameof(ReportsViewModel.kids));
The kids still won't appear in list. To fix, kids needs OnPropertyChanged:
public ObservableCollection<ItemModel> kids {
get => _kids;
set {
_kids = value;
OnPropertyChanged();
}
}
private ObservableCollection<ItemModel> _kids;
See the other code in Option B. Adapt as desired.
When you need XAML to see a DYNAMIC change, you need OnPropertyChanged. This is an implementation of INotifyPropertyChanged. Add this call to properties (that XAML binds to) of ReportsClass:
// Inheriting from `BindableObject` is one way to obtain OnPropertyChanged method.
public class ReportsClass : Xamarin.Forms.BindableObject
{
public ReportsClass(string firstName)
{
first_name = firstName;
}
public string first_name {
get => _first_name;
set {
_first_name = value;
// This tells XAML there was a change.
// Makes "{Binding first_name}" work dynamically.
OnPropertyChanged();
}
}
private string _first_name;
}
OPTION B:
Didn't find an answer anywhere that does everything correctly, so here is a complete sample, for future reference:
Remove Kids.SetBinding(...). (It can be fixed as shown in OPTION A, but its easier to get it correct in XAML, so below I show it in XAML.)
Bindings from Page to VM. See xaml below.
Create ObservableCollection with setter that does OnPropertyChanged. This informs XAML when the list is ready, so page updates. (This is an implementation of INotifyPropertyChanged, as Jason mentioned.)
Use Device.BeginInvokeOnMainThread(async () to create an async context, that is queued to run after constructor returns. (This fixes the issue Jason mentioned, which is that a constructor isn't an async context, so should not DIRECTLY call an async method such as QueryItemsAsync, or your GetKids.) This is more reliable.
PageWithQueryData.xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestXFUWP.PageWithQueryData">
<ContentPage.Content>
<StackLayout>
<CollectionView ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Name}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.EmptyView>
<Grid>
<Label Text="Loading ..." FontSize="24" TextColor="Blue" BackgroundColor="LightBlue" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
</Grid>
</CollectionView.EmptyView>
</CollectionView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
PageWithQueryData.xaml.cs:
public partial class PageWithQueryData : ContentPage
{
public PageWithQueryData()
{
InitializeComponent();
// ... other initialization work here ...
// BUT remove `Kids.Binding(...);` line. See XAML: `ItemsSource="{Binding Items}"`.
BindingContext = new VMWithQueryData();
}
}
VMWithQueryData.cs:
class VMWithQueryData : Xamarin.Forms.BindableObject
{
public VMWithQueryData()
{
// Start an async task to query.
Xamarin.Forms.Device.BeginInvokeOnMainThread(async () => {
await QueryItemsAsync();
});
// Alternative implementation: Start a background task to query.
//QueryItemsInBackground();
}
public ObservableCollection<ItemModel> Items {
get => _items;
set {
_items = value;
OnPropertyChanged();
}
}
private ObservableCollection<ItemModel> _items;
private async Task QueryItemsAsync()
{
var names = new List<string> { "One", "Two", "Three" };
bool queryOneAtATime = false;// true;
if (queryOneAtATime) {
// Show each item as it is available.
Items = new ObservableCollection<ItemModel>();
foreach (var name in names) {
// Simulate slow query - replace with query that returns one item.
await Task.Delay(1000);
Items.Add(new ItemModel(name));
}
} else {
// Load all the items, then show them.
// Simulate slow query - replace with query that returns all data.
await Task.Delay(3000);
var items = new ObservableCollection<ItemModel>();
foreach (var name in names) {
items.Add(new ItemModel(name));
}
Items = items;
}
}
// Alternative implementation, using a background thread.
private void QueryItemsInBackground()
{
Task.Run(() => {
var names = new List<string> { "One", "Two", "Three" };
bool queryOneAtATime = false;// true;
if (queryOneAtATime) {
// Show each item as it is available.
Items = new ObservableCollection<ItemModel>();
foreach (var name in names) {
// Simulate slow query - replace with query that returns one item.
System.Threading.Thread.Sleep(1000);
Items.Add(new ItemModel(name));
}
} else {
// Load all the items, then show them.
// Simulate slow query - replace with query that returns all data.
System.Threading.Thread.Sleep(3000);
var items = new ObservableCollection<ItemModel>();
foreach (var name in names) {
items.Add(new ItemModel(name));
}
Items = items;
}
});
}
}
ItemModel.cs:
public class ItemModel
{
public ItemModel(string name)
{
Name = name;
}
public string Name { get; set; }
}
This also demonstrates <CollectionView.EmptyView> to display a message to user, while the data is being queried.
For completeness, I've included an alternative QueryItemsInBackground, that uses a background thread instead of an async method. Either approach works well.
Notice inheritance from Xamarin.Forms.BindableObject. This is one way to get an implementation of INotifyPropertyChanged. You can use any other MVVM library or technique.
Move this line of code to the end of your constructor
this.BindingContext = viewmodel;

How to bind a Combobox to an ObservableCollection with SelectedItem dependant on ListBox?

I have a combobox, which draws it's items from an ObservableCollection of a custom type using Bindings. I've set the DisplayMemberPath so it displays the correct string and stuff. Now I'm fiddling with the SelectedItem/SelectedValue. It needs to be dependant on the selected item of a ListBox, which is bound to a different ObservableCollection of another custom type, but which has a property of the same type of the ComboBox list.
How can I bind this using MVVM? Is it even possible?
I've got my code here:
MainWindowViewModel.cs
private ObservableCollection<Plugin<IPlugin>> erpPlugins;
public ObservableCollection<Plugin<IPlugin>> ERPPlugins
{
get
{
return erpPlugins;
}
set
{
erpPlugins = value;
OnProprtyChanged();
}
}
private ObservableCollection<Plugin<IPlugin>> shopPlugins;
public ObservableCollection<Plugin<IPlugin>> ShopPlugins
{
get
{
return shopPlugins;
}
set
{
shopPlugins = value;
OnProprtyChanged();
}
}
private ObservableCollection<Connection> connections;
public ObservableCollection<Connection> Connections
{
get {
return connections;
}
set
{
connections = value;
}
}
public MainWindowViewModel()
{
instance = this;
ERPPlugins = new ObservableCollection<Plugin<IPlugin>>(GenericPluginLoader<IPlugin>.LoadPlugins("plugins").Where(x => x.PluginInstance.Info.Type == PluginType.ERP));
ShopPlugins = new ObservableCollection<Plugin<IPlugin>>(GenericPluginLoader<IPlugin>.LoadPlugins("plugins").Where(x => x.PluginInstance.Info.Type == PluginType.SHOP));
Connections = new ObservableCollection<Connection>
{
new Connection("test") { ERP = ERPPlugins[0].PluginInstance, Shop = ShopPlugins[0].PluginInstance } // Debug
};
}
Connection.cs
public class Connection
{
public string ConnectionName { get; set; }
public IPlugin ERP { get; set; }
public IPlugin Shop { get; set; }
public Connection(string connName)
{
ConnectionName = connName;
}
}
And the XAML snippet of my ComboBox:
<ComboBox
Margin="10,77,232,0"
VerticalAlignment="Top"
x:Name="cmbERP"
ItemsSource="{Binding ERPPlugins}"
SelectedItem="{Binding ElementName=lbVerbindungen, Path=SelectedItem.ERP}"
DisplayMemberPath="PluginInstance.Info.Name"
>
Alright, I solved it by changing the IPlugin type in the Connection to Plugin. Why I used IPlugin there in the first place is beyond my knowledge. But like this, I have the same type of Plugin everywhere.
Thanks for your help, appreciate it

Add localization resources to be shared across multiple projects

Due to architecture design specifications, I have an application that fills its views from ClassLibraries. The application itself behaves like a sort of Integrator.
Now I need to add localization resources and I can successfully achieve it by adding *.resw files but only if the control is declared inside of the Application project.
What I actually need is to being able to share those resources across the ENTIRE SOLUTION somehow.
Then, the point is to being able to translate any control's content of the solution by using localization resources, preferably using the structure explained above.
For example, I have this following view, which fills the TextBlocks' content depending on the selected language:
<ComboBox x:Name="Languages"
ItemsSource="{Binding Languages}"
SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}">
<i:Interaction.Behaviors>
<iCore:EventTriggerBehavior EventName="SelectionChanged">
<iCore:InvokeCommandAction Command="{Binding ChangeLanguage}" />
</iCore:EventTriggerBehavior>
</i:Interaction.Behaviors>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding LanguageName}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Text="{Binding Model.HelloText}" FontSize="50" Foreground="Red"/>
<TextBlock Text="{Binding Model.HowAreYouText}" FontSize="50" Foreground="Red"/>
<BFview:BFView />
</StackPanel>
Where BFView is a view stored in another project (has two dummy textblocks also)
The Model of that view:
public class MainModel : TranslatableStrings
{
private string helloText, howareuText;
public string HelloText
{
get { return this.helloText; }
set { SetProperty(ref this.helloText, value); }
}
public string HowAreYouText
{
get { return this.howareuText; }
set { SetProperty(ref this.howareuText, value); }
}
}
And the base class of the Model is just a contractual class since it has no implementation, but a base type:
public abstract class TranslatableStrings : BindableBase { }
Then, the View data context is the following one:
public class MainViewModel : BaseViewModel
{
private ObservableCollection<MainViewListRscs> languages = new ObservableCollection<MainViewListRscs>();
private ICommand changeLang;
private MainModel model = new MainModel();
public MainViewModel()
{
Languages = new ObservableCollection<MainViewListRscs>()
{
new MainViewListRscs { LanguageCode = "es-ES", LanguageName = "Español" },
new MainViewListRscs { LanguageCode = "en-EN", LanguageName = "English" },
new MainViewListRscs { LanguageCode = "fr-FR", LanguageName = "Français" },
new MainViewListRscs { LanguageCode = "de-DE", LanguageName = "Deutsch" }
};
}
public ICommand ChangeLanguage
{
get { return changeLang = changeLang ?? new DelegateCommand(OnChangeLanguageRequested); }
}
public ObservableCollection<MainViewListRscs> Languages
{
get { return this.languages; }
set
{
this.languages = value;
OnPropertyChanged();
}
}
public MainViewListRscs SelectedLanguage { get; set; }
public MainModel Model
{
get { return this.model; }
set { this.model = value; }
}
private void OnChangeLanguageRequested()
{
Logger.Debug("MAINVIEW", SelectedLanguage.LanguageName + " selected.");
TranslateManager.UpdateStrings<TranslatableStrings>(SelectedLanguage.LanguageCode, this.Model);
}
public override Task OnNavigatedFrom(NavigationEventArgs args)
{
return null;
}
public override Task OnNavigatedTo(NavigationEventArgs args)
{
return null;
}
}
And the TranslateManager:
public class TranslateManager
{
public async static void UpdateStrings<T>(string langCode, T instance) where T : TranslatableStrings
{
//Get all the classes that implement TranslatableStrings
var currentAssembly = instance.GetType().GetTypeInfo().Assembly;
var translatableClasses = currentAssembly.DefinedTypes.Where(type => type.BaseType == typeof(T)).ToList();
//Open RESX file
ResourceLoader resx = ResourceLoader.GetForCurrentView(langCode);
foreach(var Class in translatableClasses)
{
foreach(var property in Class.DeclaredProperties)
{
string value = resx.GetString(property.Name);
var vmProp = instance.GetType().GetTypeInfo().GetDeclaredProperty(property.Name);
vmProp.SetValue(instance, value);
}
}
}
}
I have achieved changing the two TextBlocks of the MainView but not the view in another project. What I would need to do is to get a list of assemblies contained in a solution. I guess that getting just this would make everything work since I'm using a generic implementation.
Any suggestion will be much appreciated.
Thanks!
Your translation files are loaded as resources. So you can access them anywhere, even in other projects by doing something like
private ResourceLoader _resourceLoader = new ResourceLoader();
var someTranslation =_resourceLoader.GetString("your_localization_key");
Wrap this code nicely into a lib so that you can have an easy access to it from everywhere, and there you go !

Multibinding XamDataGrid

I am trying to use the following code example from the Infragistics site and I'd like edits in the XamDataCards to be reflected in the XamDataGrid. However, my DataSource for the XamDataGrid is an ObservableCollection<Companies> in my ViewModel. How can I also bind to the card and relay updates back to my Companies object in the ViewModel?
<igDP:XamDataGrid x:Name="dgCompanies" Theme="IGTheme" DataSource="{Binding Companies}" SelectedDataItemsScope="RecordsOnly">
<igDP:XamDataGrid.FieldSettings>
<igDP:FieldSettings CellClickAction="SelectCell" AllowEdit="True"/>
</igDP:XamDataGrid.FieldSettings>
</igDP:XamDataGrid>
<igDP:XamDataCards x:Name="XamDataCards1"
Grid.Row="1"
DataSource="{Binding Path=SelectedDataItems, ElementName=dgCompanies}"
Theme="IGTheme">
Edit: Added ViewModel
public class CompanyMgmtViewModel : ViewModelBase
{
private ObservableCollection<Object> _Companies = null;
public ObservableCollection<Object> Companies
{
get { return _Companies; }
set
{
if (_Companies != value)
{
_Companies = value;
RaisePropertyChanged(GetPropertyName(() => Companies));
}
}
}
public CompanyMgmtViewModel()
{
this.LoadData();
}
public void LoadData()
{
ObservableCollection<Object> records = new ObservableCollection<Object>();
var results = from res in AODB.Context.TCompanies
select res;
foreach (var item in results)
if (item != null) records.Add(item);
Companies = records;
}
}
The Model/Context code is just EF Database First generated.
You would need to bind your XamDataGrid's SelectedDataItems property to a property of type object[] ie. SelectedCompanies in your ViewModel and bind to that for your XamDataCards' datasource.
The accepted answer in this thread has a sample that shows how to do this, albeit with a ListBox instead of XamDataCards:
http://www.infragistics.com/community/forums/t/89122.aspx
Just replace that ListBox with your XamDataCards control, it works and updates the XamDataGrid. The ViewModel in the example is contained in the MainWindow code-behind, so it is MVVM like you want.
more info:
http://help.infragistics.com/Help/Doc/WPF/2014.1/CLR4.0/html/xamDataGrid_Selected_Data_Items.html
IG's SelectedDataItems is an object[] :
http://help.infragistics.com/Help/Doc/WPF/2014.1/CLR4.0/html/InfragisticsWPF4.DataPresenter.v14.1~Infragistics.Windows.DataPresenter.DataPresenterBase~SelectedDataItems.html
I couldn't have gotten to this answer without Theodosius' and Ganesh's input - so thanks to them, they both had partial answers.
I first tried to bind the SelectedDataItems of the XamDataGrid to the XamDataCards by way of a property on the ViewModel as Theodosius suggested, but that wasn't enough. Thanks to Ganesh, I implemented INotifyPropertyChanged on my model objects, by inheriting from ObservableObject in MVVMLight (how did I not know the Model needed this?).
Below are the relevant pieces of code to make it work.
I also implemented PropertyChanged.Fody as documented here; that's where the TypedViewModelBase<T> and removal of RaisePropertyChanged() comes from.
I'm also creating my Model objects by using a LINQ/Automapper .Project().To<T>() call which can be found here.
Model
public class Company : ObservableObject
{
public Company() { }
public int id { get; set; }
public string strName { get; set; }
public string strDomicileCode { get; set; }
}
ViewModel
public class CompanyMgmtViewModel : TypedViewModelBase<Company>
{
private ObservableCollection<Object> _Companies = null;
private Object[] _selectedCompany = null;
public Object[] Company
{
get { return _selectedCompany; }
set
{
if (_Company != value)
{
_selectedCompany = value;
}
}
}
public ObservableCollection<Object> Companies
{
get { return _Companies; }
set
{
if (_Companies != value)
{
_Companies = value;
}
}
}
public CompanyMgmtViewModel()
{
this.LoadData();
}
public void LoadData()
{
ObservableCollection<Object> records = new ObservableCollection<Object>();
var results = AODB.Context.TCompanies.Project().To<Company>();
foreach (var item in results)
if (item != null) records.Add(item);
Companies = records;
}
}
View
<igDP:XamDataGrid x:Name="dgCompanies"
Theme="IGTheme"
DataSource="{Binding Companies, Mode=OneWay}"
SelectedDataItemsScope="RecordsOnly"
SelectedDataItems="{Binding Company}">
...
<igDP:XamDataCards x:Name="XamDataCards1"
Grid.Row="1"
DataSource="{Binding ElementName=dgCompanies, Path=SelectedDataItems}"
Theme="IGTheme">

Categories

Resources