I'm trying to make a chart (UWP-c#) which changes dynamically when It's source data changes.
For example:
xaml file:
<StackPanel>
<Button Name="scatterButton" Content="click" Click="ScatterButton_Click" />
<Charting:Chart x:Name="test_chart">
<Charting:ScatterSeries IndependentValuePath="Name" DependentValuePath="Amount" />
</Charting:Chart>
</StackPanel>
c#:
public class SmartPhone
{
public string Name { get; set; }
public int Amount { get; set; }
public int Other { get; set; }
}
public sealed partial class MainPage : Page
{
List<SmartPhone> lstSource = new List<SmartPhone>
{
new SmartPhone() { Name = "IPhone", Amount = 40, Other = 1 },
new SmartPhone() { Name = "Android", Amount = 30, Other = 1 },
new SmartPhone() { Name = "UWP", Amount = 25, Other = 2 }
};
public MainPage()
{
this.InitializeComponent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
LoadChartContent();
}
private void LoadChartContent()
{
(test_chart.Series[0] as ScatterSeries).ItemsSource = lstSource;
}
private void ScatterButton_Click(object sender, RoutedEventArgs e)
{
lstSource[0].Amount = 10;
}
}
The idea is when I click the button "Amount" value change and I want to see it change in the chart.
I tried many packages but this is the only one that really worked for me in UWP. tha NuGet is "WinRTXamlToolkit.Controls.DataVisualization".
Please try to focus on "ScatterSeries" since this is the one I need.
Thanks.
At first you should use ObservableCollection instead of List to automatically notify when items get added or removed.
To notify about changes you have to implement INotifyPropertyChanged and raise PropertyChanged event.
xaml:
<Charting:Chart x:Name="test_chart">
<Charting:ScatterSeries ItemsSource="{x:Bind LstSource}" IndependentValuePath="Name" DependentValuePath="Amount" />
</Charting:Chart>
SmartPhone class example:
public class SmartPhone : INotifyPropertyChanged
{
private int _amount;
public string Name { get; set; }
public int Amount
{
get { return _amount; }
set
{
this._amount = value;
NotifyPropertyChanged();
}
}
public int Other { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
MainPage class:
public sealed partial class MainPage : Page
{
public ObservableCollection<SmartPhone> LstSource
{
get { return lstSource; }
}
private ObservableCollection<SmartPhone> lstSource = new ObservableCollection<SmartPhone>
{
new SmartPhone() {Name = "IPhone", Amount = 10, Other = 1},
new SmartPhone() {Name = "Android", Amount = 30, Other = 1},
new SmartPhone() {Name = "UWP", Amount = 25, Other = 2}
};
public MainPage()
{
this.InitializeComponent();
//LoadChartContent();
}
private void ScatterButton_Click(object sender, RoutedEventArgs e)
{
lstSource[0].Amount = 30;
//lstSource.Add(new SmartPhone{Amount = 10, Name = "asd", Other = 2});
}
}
I hope it's all you need.
Related
The ListBox's DataSource is bound to Detail.Tags.
When I select the first row, ListBox populates as expected.
When I select the second row, the expected (and desired) result is that the ListBox simply displays nothing, because ItemB's Detail property is purposely null for demonstration purposes, so ItemB's Detail.Tags doesn't exist.
Actual result is that program crashes to desktop with System.ArgumentException: 'Complex DataBinding accepts as a data source either an IList or an IListSource.'
Minimal reproducible example:
public partial class Form1 : Form
{
private readonly IList<Item> _items;
private BindingSource _bs = new BindingSource(){ DataSource = typeof(Item) };
public Form1()
{
InitializeComponent();
_items = GenerateSampleItems();
}
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = _items;
listBox1.DataBindings.Add(new Binding("DataSource", _bs, "Detail.Tags", false, DataSourceUpdateMode.Never));
}
private void DataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count == 1)
{
_bs.DataSource = dataGridView1.SelectedRows[0].DataBoundItem;
}
else
{
_bs.DataSource = typeof(Item);
}
}
private IList<Item> GenerateSampleItems()
{
return new List<Item>()
{
new Item()
{
Name = "ItemA"
,Detail = new Detail()
{
Expiration = new DateTime(2024,1,1)
,Tags = new BindingList<Tag>(new List<Tag>()
{
new Tag()
{
TagName = "FirstT"
,TagValue = "FirstV"
}
,new Tag()
{
TagName = "SecondT"
,TagValue = "SecondV"
}
})
}
}
,new Item()
{
Name = "ItemB"
// Detail purposely omitted
}
,new Item()
{
Name = "ItemC"
// Detail purposely omitted
}
};
}
}
class Item
{
public string Name { get; set; }
public Detail Detail { get; set; }
}
public class Detail
{
public DateTime Expiration { get; set; }
public BindingList<Tag> Tags { get; set; }
}
public class Tag
{
public string TagName { get; set; }
public string TagValue { get; set; }
}
You can solve this problem by Creating a BindingSource for each model:
Main BindingSource where its DataSource property is set to a list of Item. This one is the DataGridView.DataSource.
Second BindingSource to navigate the Detail data members of the main BindingSource.
Third one to navigate and display the Tags data members of the detail's BindingSource. This one is the ListBox.DataSource.
public partial class Form1 : Form
{
private IList<Item> _items;
private BindingSource _bsItems, _bsDetail, _bsTags;
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_items = GenerateSampleItems();
_bsItems = new BindingSource(_items, null);
_bsDetail = new BindingSource(_bsItems, "Detail");
_bsTags = new BindingSource(_bsDetail, "Tags");
dataGridView1.DataSource = _bsItems;
listBox1.DataSource = _bsTags;
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);
_bsItems.Dispose();
_bsDetail.Dispose();
_bsTags.Dispose();
}
private IList<Item> GenerateSampleItems()
{
return new List<Item>()
{
new Item()
{
Name = "ItemA",
Detail = new Detail
{
Expiration = new DateTime(2024,1,1),
Tags = new BindingList<Tag>(new List<Tag>()
{
new Tag
{
TagName = "FirstT",
TagValue = "FirstV"
},
new Tag
{
TagName = "SecondT",
TagValue = "SecondV"
}
})
}
},
new Item()
{
Name = "ItemB"
// Detail purposely omitted
},
new Item()
{
Name = "ItemC"
// Detail purposely omitted
}
};
}
}
// Elsewhere within the project's namespace
public class Item
{
public string Name { get; set; }
public Detail Detail { get; set; }
// Optional: Change, remove as needed...
public override string ToString()
{
return $"Name: {Name} - Detail: {Detail}";
}
}
public class Detail
{
public DateTime Expiration { get; set; }
public BindingList<Tag> Tags { get; set; }
// Optional: Change, remove as needed...
public override string ToString()
{
var tags = $"[{string.Join(", ", Tags)}]";
return $"Expiration: {Expiration} - Tags: {tags}";
}
}
public class Tag
{
public string TagName { get; set; }
public string TagValue { get; set; }
// Optional: Change, remove as needed...
public override string ToString()
{
return $"{TagName}: {TagValue}";
}
}
That's all. No need to add DataBindings nor to handle the grid's SelectionChanged event as shown in your code snippet.
On the other hand, if you need to display the selected Item.Detail.Tags, then you need to flatten them in a list whenever the grid's selection changes and bind the result to the ListBox.
// +
using System.Linq;
public partial class Form1 : Form
{
private BindingSource _bsItems;
public Form1() => InitializeComponent();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_bsItems = new BindingSource(GenerateSampleItems(), null);
dataGridView1.DataSource = _bsItems;
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);
_bsItems.Dispose();
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
listBox1.DataSource = dataGridView1.SelectedCells
.Cast<DataGridViewCell>()
.Select(cell => cell.OwningRow).Distinct()
.Where(row => (row.DataBoundItem as Item)?.Detail != null)
.SelectMany(row => (row.DataBoundItem as Item).Detail.Tags)
.ToList();
}
}
I am trying to create a usercontrol to display groups of items from json file on windows iot core.
I have a "Create Group" button. Once pressed, it will create 64 usercontrols with respective details and display in a scrollviewer. susequently i can edit individual items in any of the 64 usercontrol then save the json file.
I have my class for the usercontrol as follow;
I have having an issue on how to create different groups of the 64 items and append all in a same json file and to subsequently display them from selection of the mentioned different groups.
Please help thanks.
Group Class
[DataContract]
public class DecoderGroup
{
[DataMember]
public int groupID{ get; set; }
[DataMember]
public string groupName{ get; set; }
[DataMember]
public int cardAddress { get; set; }
[DataMember]
public bool enabled { get; set; }
[DataMember]
public int z1label { get; set; }
[DataMember]
public int z2label { get; set; }
[DataMember]
public int z3label { get; set; }
[DataMember]
public int z4label { get; set; }
[DataMember]
public bool zone1 { get; set; }
[DataMember]
public bool zone2 { get; set; }
[DataMember]
public bool zone3 { get; set; }
[DataMember]
public bool zone4 { get; set; }
[DataMember]
public List<byte> txData { get; set; }
public DecoderGroup(int id, int address, int z1, int z2, int z3, int z4)
{
groupName = "Group";
zone1 = false;
zone2 = false;
zone3 = false;
zone4 = false;
z1label = z1;
z2label = z2;
z3label = z3;
z4label = z4;
}
}
MainPage.xaml.cs
private void AddGroup_Click(object sender, RoutedEventArgs e)
{
ZonesList_Panel.Children.Clear();
int groupid = 1;
int cardadr;
for (cardadr = 1; cardadr <= MAXCARDS; cardadr++)
{
var z4 = (4 * cardadr);
var z3 = (4 * cardadr) - 1;
var z2 = (4 * cardadr) - 2;
var z1 = (4 * cardadr) - 3;
DecoderGroupUserControl decoderGroupControl = new DecoderGroupUserControl(this, new DecoderGroup(groupid, cardadr, z1, z2, z3, z4));
ZonesList_Panel.Children.Add(decoderGroupControl);
}
}
private async void SaveGroup_Click(object sender, RoutedEventArgs e)
{
await saveGroupsToJSON(getGroups());
}
public async Task saveGroupsToJSON(List<DecoderGroup> groups)
{
var serializer = new DataContractJsonSerializer(typeof(List<DecoderGroup>));
using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(DECODERGROUPS_FILE, CreationCollisionOption.OpenIfExists))
{
serializer.WriteObject(stream, groups);
}
}
public List<DecoderGroup> getGroups()
{
List<DecoderGroup> ret = new List<DecoderGroup>();
foreach (DecoderGroupUserControl u in ZonesList_Panel.Children)
{
//add condition for group ID
ret.Add(u.decoderGroup);
}
return ret;
}
UserControl
public DecoderGroupUserControl(MainPage page, DecoderGroup group)
{
this.InitializeComponent();
mainPage = page;
this.decoderGroup = group;
Z1Name.Text = group.z1label.ToString();
Z2Name.Text = group.z2label.ToString();
Z3Name.Text = group.z3label.ToString();
Z4Name.Text = group.z4label.ToString();
}
It is recommended to use UserControl as the DateTemplate of ListView so that you don’t need to create multiple usercontrol and add them to the page. Then you could read json file and convert json objects to a collection, and you could use the collection as the Itemsource of ListView.
By implementing the INotifyPropertyChanged interface, TwoWay data binding could reflect the UI changes to the collection. Finally, you could write the changed collection to the json file.
Note that you need to download the Newtonsoft.Json to parse the json object via Manage NuGet Packages. Please refer to the following code.
MyUserControl1.xaml:
<UserControl
..>
<Grid>
<!--customize the usercontrol style-->
<StackPanel>
<StackPanel Orientation="Horizontal" >
<TextBox Margin="0,0,20,0" Text="{Binding Name,Mode=TwoWay}" BorderThickness="0"/>
<TextBox Text="{Binding Job,Mode=TwoWay}" BorderThickness="0"/>
</StackPanel>
<TextBox Text="{Binding Age,Mode=TwoWay}" BorderThickness="0"/>
</StackPanel>
</Grid>
</UserControl>
MainPage.xaml:
<Page..>
<Grid>
<StackPanel>
<ListView ItemsSource="{x:Bind Results,Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Person">
<local:MyUserControl1>
</local:MyUserControl1>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button x:Name="SaveButton" Content="Save" Click="SaveButton_Click"/>
</StackPanel>
</Grid>
</Page>
MainPage.xaml.cs:
namespace WriteJson
{
public sealed partial class MainPage : Page
{
public ObservableCollection<Person> Persons { get; set; }
public ObservableCollection<Person> Results { get; set; }
public string path;
public MainPage()
{
this.InitializeComponent();
CreateJsonFile();
path = ApplicationData.Current.LocalFolder.Path + "\\info.json";
Results = JsonConvert.DeserializeObject<ObservableCollection<Person>>(File.ReadAllText(path));
Debug.WriteLine("bind successfully");
}
public async void CreateJsonFile()
{
//check if info.json exists, if it doesn't exist, create it
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file;
try
{
file = await folder.GetFileAsync("info.json");
}
catch
{
await folder.CreateFileAsync("info.json");
Persons = new ObservableCollection<Person>()
{
new Person(){Name="tom",Job="teacher",Age=24},
new Person(){Name="lily",Job="nurse",Age=20},
new Person(){Name="ming",Job="student",Age=26},
new Person(){Name="kiki",Job="lawyer",Age=28},
new Person(){Name="jack",Job="worker",Age=21},
};
path = ApplicationData.Current.LocalFolder.Path + "\\info.json";
File.WriteAllText(path, JsonConvert.SerializeObject(Persons));
Debug.WriteLine("create a json file successfully");
}
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
File.WriteAllText(path, JsonConvert.SerializeObject(Results));
Debug.WriteLine("save successfully");
}
}
public class Person:INotifyPropertyChanged
{
private string name;
private string job;
private int age;
public string Name
{
get { return name; }
set
{
name = value;
RaisePropertyChanged("Name");
}
}
public string Job
{
get { return job; }
set
{
job = value;
RaisePropertyChanged("Job");
}
}
public int Age
{
get { return age; }
set
{
age = value;
RaisePropertyChanged("Age");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyname=null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
}
I have been reading documentation for several days now but I can't get it working, no matter what I try. I have Basic Row chart and want to display as a graph time spent. My bar title and value are changing constantly (more items getting added). I am able to add bars with my current code, but I am not able to add title for each added bar. Only first title / first bar title is visible, all the others / coming are not visible.
How to add title and value in a proper way? (I am already familiar with documentation https://lvcharts.net/App/examples/v1/wf/Basic%20Row)
Here is my code (you can see from commented out sections what has been tried yet):
public static SeriesCollection SeriesCollection { get; set; }
public static string[] Labels { get; set; }
public static List<string> LabelsList { get; set; }
public static Func<double, string> Formatter { get; set; }
public AppUsageBarGraph()
{
InitializeComponent();
LabelsList = new List<string>();
SeriesCollection = new SeriesCollection
{
new RowSeries
{
Values = new ChartValues<double> { },
DataLabels = true
}
};
DataContext = this;
}
public static void UpdateChart()
{
SeriesCollection[0].Values.Clear();
LabelsList.Clear();
//Labels = MainProcess.ActivityLogGrouped.Rows.Cast<DataRow>().Select(row => row["Window Title"].ToString()).ToArray();
foreach (DataRow row in MainProcess.ActivityLogGrouped.Rows)
{
SeriesCollection[0].Values.Add(Convert.ToDouble(row["Time Spent"]));
//SeriesCollection[0]. = row["Time Spent"].ToString());
LabelsList.Add(row["Window Title"].ToString());
}
//MessageBox.Show(Labels[0].ToString());
Labels = LabelsList.ToArray();
//foreach (var item in Labels)
//{
// MessageBox.Show(item);
//}
//Labels = new[]
// {
// "Shea Ferriera",
// "Maurita Powel",
// "Scottie Brogdon",
// "Teresa Kerman",
// "Nell Venuti",
// "Anibal Brothers",
// "Anderson Dillman"
// };
//Formatter = value => value.ToString("N");
}
The key is to use a ObservableCollection<string> instead of a string[].
I also recommend to use a model to encapsulate the actual chart data points. I introduced the class DataModel for this reason.
The following example shows how to dynamically bind values and labels to the chart. I should say that making everything public static is a very bad smelling code design.
MainWindow.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<wpf:CartesianChart Height="500">
<CartesianChart.Series>
<RowSeries Values="{Binding ChartModel.RowSeries}"
Configuration="{Binding ChartModel.RowSeriesConfiguration}"/>
</CartesianChart.Series>
<CartesianChart.AxisY>
<Axis Labels="{Binding ChartModel.RowSeriesLabels}" />
</CartesianChart.AxisY>
</CartesianChart>
</Window>
ViewModel.cs
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
this.ChartModel = new ChartModel();
}
public void UpdateChart()
{
foreach (DataRow row in MainProcess.ActivityLogGrouped.Rows)
{
if (double.TryParse(row["Time Spent"], out double value)
{
string label = row["Window Title"];
var newDataModel = new DataModel(value, label);
this.ChartModel.RowSeries.Add(newDataModel);
this.ChartModel.RowSeriesLabels.Add(newDataModel.Label);
}
}
}
public ChartModel ChartModel { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
ChartModel.cs
public class ChartModel : INotifyPropertyChanged
{
public ChartModel()
{
// Initialize chart
this.RowSeries = new ChartValues<DataModel>()
{
new DataModel(20, "Shea Ferriera"),
new DataModel(100, "Maurita Powel"),
new DataModel(60, "Scottie Brogdon"),
};
// Create labels
this.RowSeriesLabels = new ObservableCollection<string>();
foreach (DataModel dataModel in this.RowSeries)
{
this.RowSeriesLabels.Add("dataModel.Label");
}
// DatModel to value mapping
this.RowSeriesConfiguration = new CartesianMapper<DataModel>()
.X(dataModel => dataModel.Value);
}
public CartesianMapper<DataModel> RowSeriesConfiguration { get; set; }
public ChartValues<DataModel> RowSeries { get; set; }
public ObservableCollection<string> RowSeriesLabels { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
DataModel.cs
public class DataModel
{
public DataModel(double value, string label)
{
this.Value = value;
this.Label = label;
}
public double Value { get; set; }
public string Label { get; set; }
}
I created a custom picker with the help of Lucas Zhang which you can check in the link
xamarin custom multiple picker
Now I have another question with this problem. When user select a group or groups, I need access to these selected parameters.
public class Grup
{
public int ID { get; set; }
public string GroupName { get; set; }
public Nullable<int> SubsID { get; set; }
}
This is the model I use. Picker reads Groupnames through ViewModel which is shown below.
public class NewUserViewModel
{
public List<Grup> GroupList { get; set; }
public List<Grup> SelectedGroup { get; set; }
}
And I want save these parameters which came from every pickers in the view to here and furthermore I will send them to database through API.Question is how can I access these IDs when user select them and click save button.
An easy way to do this is to listen for picker's selection events and then get the result of each selection by iterating over the pickerStack
like this(base on Lucas Zhang's sample):
in PickerView :
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PickerView : ContentView
{
public Group SelectGroup; // add the SelectGroup property which save the result after you select
public ObservableCollection<Group> pickerSource { get; set; }
public PickerView(ObservableCollection<Group> source) //here i change the source to your Group model
{
InitializeComponent();
picker.ItemsSource = source;
}
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
var stack = this.Parent as StackLayout;
stack.Children.Remove(this);
}
private void picker_SelectedIndexChanged(object sender, EventArgs e)
{
var picker = sender as Picker;
SelectGroup = (Group)picker.SelectedItem;
}
}
in PickerView.xaml just add the SelectedIndexChanged event:
<Picker Grid.Column="0" x:Name="picker" Title="{Binding GroupName}" ItemDisplayBinding="{Binding ID}" TitleColor="Red" SelectedIndexChanged="picker_SelectedIndexChanged" />
in your page :
public partial class MutiPicker : ContentPage
{
public MutiPicker()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
var source = new ObservableCollection<Group>() { new Group() { ID=111,GroupName="AAA",SubsID=1}, new Group() { ID = 222, GroupName = "BBB", SubsID = 2 }, new Group() { ID = 333, GroupName = "CCC", SubsID = 3 } };
pickerStack.Children.Add(new PickerView(source));
}
//iterate over your pickerviews
private void Update_Clicker(object sender, EventArgs e)
{
foreach (var pickerview in pickerStack.Children)
{
if (pickerview is PickerView && ((PickerView)pickerview).SelectGroup != null)
{
var selectgroup = ((PickerView)pickerview).SelectGroup;//here you will get your select group,then you could get its ID ,GroupName or SubsID
}
}
}
}
I have two bound textboxes in my View.
<TextBox Text="{Binding BookingWizard.CustomerView.Email,Mode=TwoWay}" />
<TextBox Text="{Binding BookingWizard.CustomerView.ContactNo,Mode=TwoWay}" />
I can populate these fields when another textbox has lost its focus. the code behind for that bit is:
private void txtFirstName_LostFocus(object sender, RoutedEventArgs e)
{
LookUpEmailAndContactNo();
}
private void LookUpEmailAndContactNo()
{
var vm = this.DataContext as ApplicationViewModel;
var customer = vm.BookingWizard.LookUpEmailAndContactNo();
//etc
vm.BookingWizard.CustomerView.Email = customer.Email;
}
public Customer LookUpEmailAndContactNo()
{
var res= InformedWorkerBusinessService.Customer.GetEmailAndContactNo(CustomerView.FName, CustomerView.SName);
if (res!=null)
{
CustomerView.Email = res.Email;
CustomerView.ContactNo = res.ContactNo;
}
return CustomerView;
}
This is the screenshot of my data context when i set a break-point in the LookUpEmailAndContactNo event:
As you can see the data context does have these values but I cannot see what is wrong with my UI binding?
ADDITIONAL:
I set my view model at the App entry point:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ApplicationView app = new ApplicationView();
ApplicationViewModel context = new ApplicationViewModel();
context.ActiveRecord = new ActiveRecord();
context.CustomerSearch = new CustomerSearch();
context.BookingWizard = new BookingWizard();
context.BookingWizard.CustomerView = new InformedWorkerModel.Customer();
context.BookingWizard.JobView = new InformedWorkerModel.Job();
app.DataContext = context;
app.Show();
}
}
This is inside my BookingWizard class:
public class BookingWizard : ViewModelBase, IDataErrorInfo
{
Customer _Customer;
public bool IsExistingCustomer { get; set; }
public IEnumerable<string> FNames
{
get
{
if (CustomerView.SName == null)
{
CustomerView.SName = string.Empty;
}
return InformedWorkerBusinessService.Customer.GetFirstNames(CustomerView.SName);
}
}
public Customer LookUpEmailAndContactNo()
{
var res= InformedWorkerBusinessService.Customer.GetEmailAndContactNo(CustomerView.FName, CustomerView.SName);
if (res!=null)
{
CustomerView.Email = res.Email;
CustomerView.ContactNo = res.ContactNo;
}
return CustomerView;
}
public Customer CustomerView
{
get { return _Customer; }
set
{
_Customer = value; RaisePropertyChanged("CustomerView");
}
}
}
and in my Customer Class:
[Table("Customer")]
public class Customer
{
[AutoIncrement]
[PrimaryKey]
public int CustomerId { get; set; }
public string SName { get; set; }
public string FName { get; set; }
public string ContactNo { get; set; }
public string Email { get ; set; }
}