Sorting on multiple column header in liferay searchcontainer - liferay-6

i done with sorting on single column header of liferay searchcontainer in liferay 6.0.6.
now i want to apply sorting on multiple fields i.e FirstName,LastName,Date either in asc or desc order.
can anybody help me out..
Thanks in advance....

view.jsp
<%
PortalPreferences portalPrefs = PortletPreferencesFactoryUtil.getPortalPreferences(request);
String orderByCol = ParamUtil.getString(request, "orderByCol");
String orderByType = ParamUtil.getString(request, "orderByType");
System.out.println("Col "+ orderByCol);
if (Validator.isNotNull(orderByCol) && Validator.isNotNull(orderByType)) {
portalPrefs.setValue("NAME_SPACE", "order-by-col", orderByCol);
portalPrefs.setValue("NAME_SPACE", "order-by-type", orderByType);
} else {
orderByCol = portalPrefs.getValue("NAME_SPACE", "order-by-col", "Date");
orderByType = portalPrefs.getValue("NAME_SPACE", "order-by-type", "asc");
}
%>
<liferay-ui:search-container delta='20' emptyResultsMessage="No Form Submitted" orderByCol="<%= orderByCol %>" orderByType="<%= orderByType %>">
<liferay-ui:search-container-results>
<%
List<User> userList = UserLocalServiceUtil.getUsers(-1,-1);
OrderByComparator orderByComparator =
CustomComparatorUtil.getUserOrderByComparator(orderByCol, orderByType);
Collections.sort(userList,orderByComparator);
results = ListUtil.subList(userList, searchContainer.getStart(),
searchContainer.getEnd());
if (userList.size()< total)
{total = userList.size();
}
pageContext.setAttribute("results", results);
pageContext.setAttribute("total", total);
%>
</liferay-ui:search-container-results>
<liferay-ui:search-container-row
className="com.liferay.portal.model.User"
modelVar="user">
<liferay-ui:search-container-column-text
name="Screen Name"
property="screenName"
orderable="<%= true %>"
orderableProperty="screenName"
/>
<liferay-ui:search-container-column-text
name="Email"
property="emailAddress"
orderable="<%= true %>"
orderableProperty="emailAddress"
/>
<liferay-ui:search-container-column-text
name="Date"
property="createDate"
orderable="<%= true %>"
/>
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
CustomComparatorUtil
public static OrderByComparator getUserOrderByComparator(
String orderByCol, String orderByType) {
boolean orderByAsc = false;
if (orderByType.equals("asc")) {
orderByAsc = true;
}
OrderByComparator orderByComparator = null;
System.out.println("Custom "+ orderByCol);
if (orderByCol.equalsIgnoreCase("screenName")) {
System.out.println("1");
orderByComparator = new FirstNameComparator(orderByAsc);
}
else if (orderByCol.equalsIgnoreCase("emailAddress")) {
System.out.println("2");
orderByComparator = new EmailComparator(orderByAsc);
}
else if (orderByCol.equalsIgnoreCase("Date")) {
System.out.println("3");
orderByComparator = new DateComparator(orderByAsc);
}/*
else if (orderByCol.equalsIgnoreCase("Job Title")) {
orderByComparator = new JobTitleComparator(orderByAsc);
}*/
return orderByComparator;
}
FirstNameComparator
public static String ORDER_BY_ASC = "status ASC";
public static String ORDER_BY_DESC = "status DESC";
public FirstNameComparator()
{
this(false);
}
public FirstNameComparator(boolean asc) {
_asc = asc;
}
public int compare(Object obj1, Object obj2) {
User instance1 = (User) obj1;
User instance2 = (User) obj2;
int value = instance1.getFirstName().toLowerCase().compareTo(instance2.getFirstName().toLowerCase());
if(_asc)
{
return value;
} else
{
return -value;
}
}
public String getOrderBy() {
if (_asc) {
return ORDER_BY_ASC;
}
else {
return ORDER_BY_DESC;
}
}
private boolean _asc;
}
similarly u can make class for emailaddress and date..

Related

reactive forms: use one validator for multiple fields

I'm using angular 2 reactive forms and made a validator for a date of birth field. The validator is working, but it turns out the date of birth field is split into three new field: year, month, day. They all have their own validators. My question is, how can I change my code so my original date of birth validator works on three fields.
my original validator that checks one field.
input(2000/12/12) is valid
export function dobValidator(control) {
const val = control.value;
const dobPattern = /^\d{4}\/\d{2}\/\d{2}$/ ;
const comp = val.split('/');
const y = parseInt(comp[0], 10);
const m = parseInt(comp[1], 10);
const d = parseInt(comp[2], 10);
const jsMonth = m - 1;
const date = new Date(y, jsMonth, d);
const isStringValid = dobPattern.test(control.value);
const isDateValid = (date.getFullYear() === y && date.getMonth() === jsMonth && date.getDate() === d);
return (isStringValid && isDateValid) ? null : { invalidDob: ('Date of birth not valid') };
};
new html with 3 fields
year has a validator that checks the year
day has a validator that checks if the input is between 1 and 31
month has a validator that checks if the input is between 1 and 12.
I want to combine the above input of the three field into a new string and use my original date of birth validator.
<label>Date of birth :</label>
<div>
<div class="col-xs-1">
<input required type="text" formControlName="day" class="form-control" placeholder="dd" id="day"/>
<p *ngIf="form.controls.day.dirty && form.controls.day.errors">{{ form.controls.day.errors.invalidDay }}</p>
</div>
<div class="col-xs-1">
<input required type="text" formControlName="month" class="form-control" placeholder="mm" id="month"/>
<p *ngIf="form.controls.month.dirty && form.controls.month.errors">{{ form.controls.month.errors.invalidMonth }}</p>
</div>
<div class="col-xs-2">
<input required type="text" formControlName="year" class="form-control" placeholder="yyyy" id="year"/>
<p *ngIf="form.controls.year.dirty && form.controls.year.errors">{{ form.controls.year.errors.invalidYear }}</p>
</div>
</div>
<div>
<button type="submit" [disabled]="form.invalid">Submit</button>
</di>
I have created a validator for comparing two dates (their format is NgbDateStruct - as used in ng-bootstrap package's datepickers)
import { Directive, forwardRef, Attribute } from '#angular/core';
import { Validator, AbstractControl, NG_VALIDATORS, ValidatorFn } from '#angular/forms';
import { NgbDateStruct } from "#ng-bootstrap/ng-bootstrap";
import { toDate } from "../helpers/toDate";
export function dateCompareValidator(compareToControl: string, compareToValue: NgbDateStruct, compareType: string, reverse: boolean, errorName: string = 'dateCompare'): ValidatorFn {
return (c: AbstractControl): { [key: string]: any } => {
let compare = function (self: Date, compareTo: Date): any {
console.log('comparing ', compareType.toLowerCase());
console.log(self);
console.log(compareTo);
if (compareType.toLowerCase() === 'ge') {
if (self >= compareTo) {
return true;
} else {
return false;
}
} else if (compareType.toLowerCase() === 'le') {
if (self <= compareTo) {
return true;
} else {
return false;
}
}
return false;
};
// self value
let v = c.value;
// compare vlaue
let compareValue: Date;
let e;
if (compareToValue) {
compareValue = toDate(compareToValue);
} else {
e = c.root.get(compareToControl);
if (e) {
compareValue = toDate(e.value);
}
else {
// OTHER CONTROL NOT FOUND YET
return null;
}
}
let controlToValidate: AbstractControl = reverse ? e : c;
// validate and set result
let error = null;
let result = compare(toDate(c.value), compareValue);
if (result === true) {
console.log('clearing errors', compareToControl);
if (controlToValidate.errors) {
delete controlToValidate.errors[errorName];
if (!Object.keys(controlToValidate.errors).length) {
controlToValidate.setErrors(null);
}
}
else {
console.log('errors property not found in control', controlToValidate);
}
} else {
error = {};
error[errorName] = false;
controlToValidate.setErrors(error);
console.log(controlToValidate.errors);
console.log(controlToValidate.value);
console.log('Error Control', controlToValidate);
console.log('returning errors');
}
return reverse ? null : error;
}
}
Couldn't manage to modify much lot to best describe here as an answer but I believe you would get your query answered in this validator function code.
Note:
Function toDate() used in the code is a small function I created to convert NgbDateStruct into a javascript date object so that comparing dates can get easier. Here goes its implementation:
import { NgbDateStruct } from "#ng-bootstrap/ng-bootstrap"
export function toDate(ngbDate: NgbDateStruct): Date {
return ngbDate != null ? new Date(Date.UTC(ngbDate.year, ngbDate.month, ngbDate.day)) : null;
}

LoadBy method returns null if provided parameter is 0

My model contains an entity with a numeric property:
<cf:entity name="Land">
<cf:property name="Id" key="true" />
<cf:property name="Landcode" typeName="ushort" nullable="false" usePersistenceDefaultValue="false" />
<cf:method name="LoadByLandcode"
body="LOADONE(ushort landCode) WHERE Landcode = #landcode">
</cf:method>
</cf:entity>
The generated code for the LoadByLandcode method looks like this:
public static Land LoadByLandcode(ushort landCode)
{
if ((landCode == CodeFluentPersistence.DefaultUInt16Value))
{
return null;
}
Land land = new Land();
CodeFluent.Runtime.CodeFluentPersistence persistence = CodeFluentContext.Get(BusinessLayerStoreName).Persistence;
persistence.CreateStoredProcedureCommand(null, "Land", "LoadByLandcode");
persistence.AddParameter("#landCode", landCode);
System.Data.IDataReader reader = null;
try
{
reader = persistence.ExecuteReader();
if ((reader.Read() == true))
{
land.ReadRecord(reader, CodeFluent.Runtime.CodeFluentReloadOptions.Default);
land.EntityState = CodeFluent.Runtime.CodeFluentEntityState.Unchanged;
return land;
}
}
finally
{
if ((reader != null))
{
reader.Dispose();
}
persistence.CompleteCommand();
}
return null;
}
Why does CodeFluent return null if the provided landCode parameter is 0?
I do not want this to happen, because landCode 0 is also a valid value in the database.
How can I change this behaviour?
The parameter of the method uses the persistence default value (0 by default). So to avoid the default value check, you have to indicate the parameter is nullable:
<cf:method name="LoadByLandcode"
body="LOADONE(Landcode?) WHERE Landcode = #Landcode">
</cf:method>
public static Land LoadByLandcode(ushort landcode)
{
Land land = new Land();
CodeFluent.Runtime.CodeFluentPersistence persistence = CodeFluentContext.Get(Constants.StoreName).Persistence;
persistence.CreateStoredProcedureCommand(null, "Land", "LoadByLandcode");
persistence.AddRawParameter("#Landcode", landcode);
System.Data.IDataReader reader = null;
try
{
reader = persistence.ExecuteReader();
if ((reader.Read() == true))
{
land.ReadRecord(reader, CodeFluent.Runtime.CodeFluentReloadOptions.Default);
land.EntityState = CodeFluent.Runtime.CodeFluentEntityState.Unchanged;
return land;
}
}
finally
{
if ((reader != null))
{
reader.Dispose();
}
persistence.CompleteCommand();
}
return null;
}

web.api only serializing hidden fields

I'm experiencing a strange behaviour.
My web.api is returning only hiddenfields from my ObjectCollection on a GET request.
This is my controller:
// GET: api/UserDocuments
[Route("api/UserDocuments/User/{userName}")]
public List<DocIndex> Get(string userName)
{
User usuari = Humanisme.User.LoadByUserName(userName);
List<DocIndex> resposta = DocumentCollection.LoadIndexPerUsuari(usuari);
return resposta;
}
And this is the object as it gets generated from the BOM:
namespace Humanisme
{
using CodeFluent.Runtime;
using CodeFluent.Runtime.Utilities;
// CodeFluent Entities generated (http://www.softfluent.com). Date: Tuesday, 01 March 2016 11:52.
// Build:1.0.61214.0820
[System.CodeDom.Compiler.GeneratedCodeAttribute("CodeFluent Entities", "1.0.61214.0820")]
[System.SerializableAttribute()]
[System.ComponentModel.DataObjectAttribute()]
public partial class DocIndex : CodeFluent.Runtime.ICodeFluentLightEntity
{
private int _id = -1;
[System.NonSerializedAttribute()]
private Humanisme.User _user = ((Humanisme.User)(null));
private string _lat = default(string);
private string _lon = default(string);
private string _etapaVital = default(string);
private string _solvencia = default(string);
private int _valoracio = CodeFluentPersistence.DefaultInt32Value;
private System.DateTime _data = CodeFluentPersistence.DefaultDateTimeValue;
private string _nom = default(string);
public DocIndex()
{
}
[System.ComponentModel.DefaultValueAttribute(((int)(-1)))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=false, Type=typeof(int))]
[System.ComponentModel.DataObjectFieldAttribute(true)]
public int Id
{
get
{
return this._id;
}
set
{
this._id = value;
}
}
[System.Xml.Serialization.XmlIgnoreAttribute()]
public Humanisme.User User
{
get
{
return this._user;
}
set
{
this._user = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Lat
{
get
{
return this._lat;
}
set
{
this._lat = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Lon
{
get
{
return this._lon;
}
set
{
this._lon = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string EtapaVital
{
get
{
return this._etapaVital;
}
set
{
this._etapaVital = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Solvencia
{
get
{
return this._solvencia;
}
set
{
this._solvencia = value;
}
}
[System.ComponentModel.DefaultValueAttribute(CodeFluentPersistence.DefaultInt32Value)]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=false, Type=typeof(int))]
public int Valoracio
{
get
{
return this._valoracio;
}
set
{
this._valoracio = value;
}
}
[System.Xml.Serialization.XmlElementAttribute(IsNullable=false, Type=typeof(System.DateTime))]
public System.DateTime Data
{
get
{
return this._data;
}
set
{
this._data = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Nom
{
get
{
return this._nom;
}
set
{
this._nom = value;
}
}
protected virtual void ReadRecord(System.Data.IDataReader reader, CodeFluent.Runtime.CodeFluentReloadOptions options)
{
if ((reader == null))
{
throw new System.ArgumentNullException("reader");
}
if ((((options & CodeFluent.Runtime.CodeFluentReloadOptions.Properties)
== 0)
== false))
{
this._id = CodeFluentPersistence.GetReaderValue(reader, "Id", ((int)(-1)));
this._user = new Humanisme.User();
CodeFluent.Runtime.CodeFluentLightWeightPersistence.ReadRecord(reader, this._user, null, new CodeFluent.Runtime.Utilities.Pair<string, string>("Id", "User_Id"));
this._lat = CodeFluentPersistence.GetReaderValue(reader, "Lat", ((string)(default(string))));
this._lon = CodeFluentPersistence.GetReaderValue(reader, "Lon", ((string)(default(string))));
this._etapaVital = CodeFluentPersistence.GetReaderValue(reader, "EtapaVital", ((string)(default(string))));
this._solvencia = CodeFluentPersistence.GetReaderValue(reader, "Solvencia", ((string)(default(string))));
this._valoracio = CodeFluentPersistence.GetReaderValue(reader, "Valoracio", ((int)(CodeFluentPersistence.DefaultInt32Value)));
this._data = CodeFluentPersistence.GetReaderValue(reader, "Data", ((System.DateTime)(CodeFluentPersistence.DefaultDateTimeValue)));
this._nom = CodeFluentPersistence.GetReaderValue(reader, "Nom", ((string)(default(string))));
}
}
void CodeFluent.Runtime.ICodeFluentLightEntity.ReadRecord(System.Data.IDataReader reader)
{
this.ReadRecord(reader, CodeFluent.Runtime.CodeFluentReloadOptions.Default);
}
}
}
Calling the web.api get method returns this JSON:
[
{
"_id": 1,
"_lat": null,
"_lon": null,
"_etapaVital": null,
"_solvencia": null,
"_valoracio": 0,
"_data": "0001-01-01T00:00:00",
"_nom": null
}
]
Serializer (from WebApiConfig.cs)
JsonMediaTypeFormatter jsonFormatter = (JsonMediaTypeFormatter)config.Formatters.FirstOrDefault(f => f is JsonMediaTypeFormatter);
if (jsonFormatter != null)
{
// jsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Include;
jsonFormatter.UseDataContractJsonSerializer = true;
}
The classes generated by CodeFluent Entities are decorated by SerializableAttribute. This attribute changes the way Json.NET serialize or deserialize the object. You can configure Json.NET to ignore this attribute:
JsonMediaTypeFormatter jsonFormatter = (JsonMediaTypeFormatter)config.Formatters.FirstOrDefault(f => f is JsonMediaTypeFormatter);
if (jsonFormatter != null)
{
jsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableAttribute = true
};
}
http://james.newtonking.com/archive/2012/04/11/json-net-4-5-release-2-serializable-support-and-bug-fixes
Json.NET now detects types that have the SerializableAttribute and serializes all the fields on that type, both public and private, and ignores the propertie
So you can use the service producer which will add the DataMemberAttribute or you can use the Json.NET Aspect to automatically add specific Json.NET attribute: Newtonsoft.Json.JsonObjectAttribute and Newtonsoft.Json.JsonPropertyAttribute.
Finally found!
When dealing with web.api never, never, never forget to add the "Service Producer" subproducer attached to the standard BOM Producer in your model project.
You'll never notice any problem but at serializing when no attributes will be processed and only hidden properties (object fields) will be serialized at output.
Sorry for the nerd mistake, happy for the lesson learned.
Again, thanks Meziantou. You would never figured where the issue was originated, mainly because I didn't carried all the project details to the question.

Entity Framework is not providing me IDs when calling back

I'm using a ViewModel (RoleVM) with a collection of ViewModels (RolePermissionVM) for this particular edit view. The view displays the RoleVM fields, and a checkbox list of RolePermissionVM. Each row in the checkbox list has a hiddenFor for the ID of the RolePermission.
When I save the form, my controller correctly writes the data to the database, adding or updating records. However, I would like the user to remain on the page, so I call the View again, but trying to get an updated model so that I have the IDs for any newly created RolePermissionVM objects. I am not getting the new IDs into the HiddenFor fields.
Here's my class:
public class RolePermissionVM
{
public int? RolePermissionId { get; set; }
public int RoleId { get; set; }
public int PermissionId { get; set; }
public string PermissionName { get; set; }
public bool IsActive { get; set; }
}
My controller code:
private RoleVM GetRoleVm(int id)
{
var thisRoleVm = (from r in db.Role
where r.RoleId == id
select new RoleVM
{
RoleId = r.RoleId,
RoleName = r.RoleName,
RoleDescription = r.RoleDescription,
OwnerId = r.OwnerId,
IsActive = r.IsActive
}).FirstOrDefault();
thisRoleVm.RolePermission = (from p in db.Permission
join rPerm in
(from rp in db.RolePermission
where rp.RoleId == id
select rp)
on p.PermissionId equals rPerm.PermissionId into pp
from rps in pp.DefaultIfEmpty()
select new RolePermissionVM
{
RolePermissionId = (int?)rps.RolePermissionId,
RoleId = id,
PermissionId = p.PermissionId,
PermissionName = p.PermissionName,
IsActive = (rps.IsActive == null ? false : rps.IsActive)
})
.OrderBy(p => p.PermissionName).ToList();
return thisRoleVm;
}
[HttpPost, ActionName("_roleedit")]
[ValidateAntiForgeryToken]
public ActionResult _RoleEdit(RoleVM editedRole)
{
//...
if (ModelState.IsValid)
{
var dbRole = db.Role.Find(editedRole.RoleId);
dbRole.RoleName = editedRole.RoleName;
dbRole.RoleDescription = editedRole.RoleDescription;
dbRole.OwnerId = editedRole.OwnerId;
foreach (var thisPerm in editedRole.RolePermission) // RolePermission here is the ViewModel, not the actual model
{
if (thisPerm.RolePermissionId != null && thisPerm.RolePermissionId > 0)
{
// We have a record for this, let's just update it
var thisRolePerm =
dbRole.RolePermission.FirstOrDefault(rp => rp.RolePermissionId == thisPerm.RolePermissionId);
thisRolePerm.IsActive = thisPerm.IsActive;
db.Entry(thisRolePerm).State = EntityState.Modified;
}
else
{
if (thisPerm.IsActive)
{
// New and active, so we add it
dbRole.RolePermission.Add(new RolePermission
{
RoleId = editedRole.RoleId,
PermissionId = thisPerm.PermissionId,
IsActive = true
});
}
}
}
db.Entry(dbRole).State = EntityState.Modified;
db.SaveChanges(User.ProfileId);
var newEditedRole = GetRoleVm(editedRole.RoleId); // We don't get the new IDs here, but I would like to
newEditedRole.ResponseMessage = "Saved Successfully";
return View(newEditedRole); // This should have the new RolePermissionId values, but it doesn't.
}
editedRole.ResponseMessage = "Error Saving";
return View(editedRole);
}
The partial view used for each row of the CheckBox list:
#using PublicationSystem.Tools
#model PublicationSystem.Areas.Admin.Models.RolePermissionVM
<li class="editorRow ui-state-default removable-row">
#using (Html.BeginCollectionItem("RolePermission"))
{
<div class="row">
#Html.HiddenFor(model => model.RolePermissionId)
#Html.HiddenFor(model => model.RoleId)
#Html.HiddenFor(model => model.PermissionId)
#Html.HiddenFor(model => model.PermissionName)
<div class="col-md-7">
#Html.DisplayFor(model => model.PermissionName, new {htmlAttributes = new {#class = "form-control"}})
</div>
<div class="col-md-3">
#Html.CheckBoxFor(model => model.IsActive, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
}
</li>
var newEditedRole = GetRoleVm(editedRole.RoleId); should be calling the database to get the updated IDs, but it does not. I think the issue is the DBContext is using a cached copy.
So, why do the new database generated IDs not get pulled back? How can I fix that? Is there a more efficient way to do this?
You have to call return RedirectToAction("ViewName") instead of return View(newEditedRole);
Another way is removing the value from the ModelState, so it will be updated on view:
ModelState.Remove("RoleId")
model.RoleId = dbRole.RoleId
I think return RedirectToAction("ViewName") is better/more reliable choice.

Get image files from Local Folder to display in the UI at runtime fails

I used below codes to retrieve image files from LocalFolder
Total images files is 20 in LocalFolder
The problem:
Only 8 images are displayed and the rest is blank.
Why the rest can not be displayed?
Can bind the BitmapImage file to the image Control as below base on MVVM ?
Example : imageURL ="ms-appdata:///local/imgfile.jpg"
---- In XAML : PhotoView.xaml
<Image x:Name="Img" Source="{Binding ImageUrl}" Stretch="UniformToFill"/>
<TextBlock FontSize="23" Text="{Binding Unit_Price}" Height="23" Margin="3,1,3,0"/>
<TextBlock FontSize="23" Text="{Binding Description}" Height="23" Width="300" Margin="1,1,1,0/>
--- In code behind: PhotoView
ItemsViewModel itemsViewModel = null;
ObservableCollection items = null;
itemsViewModel = new ItemsViewModel();
items = itemsViewModel.GetItems();
//-- GridViewControl
ItemsViewSource.Source = items;
ItemsGridView.SelectedItem = null;
-------------MVVM
--------- Model :
class ItemViewModel : ViewModelBase
{
private string imageurl = string.Empty;
public string ImageUrl
{
get
{ return imageurl; }
set
{
if (imageurl == value)
{ return; }
imageurl = value;
isDirty = true;
RaisePropertyChanged("ImageUrl");
}
}
private decimal unit_price = 0;
public decimal Unit_Price
{
get
{ return unit_price; }
set
{
if (unit_price == value)
{ return; }
unit_price = value;
isDirty = true;
RaisePropertyChanged("Unit_Price");
}
}
}
---------- View Model
class ItemsViewModel : ViewModelBase
{
private ObservableCollection items;
public ObservableCollection Items
{
get
{
return items;
}
set
{
items = value;
RaisePropertyChanged("Items");
}
}
public ObservableCollection GetItems()
{
items = new ObservableCollection();
using (var db = new SQLite.SQLiteConnection(App.DBPath))
{
var query = db.Table().Where(c=> c.CompanyName == Company).OrderBy(c => c.No);
foreach (var _item in query)
{
var item = new ItemViewModel()
{
No = _item.No,
ImageUrl = "ms-appdata:///local/" + _item.PictureFilename,
Unit_Price = _item.Unit_Price,
Description = _item.Description
};
items.Add(item);
}
}
return items;
}
Try to bind ImageSource (not string)
Try to copy the Image folder in the Folder wherever you are using or Register the Every image in Register.resx and call the image by its name given in the Register